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; 016 017import java.util.HashMap; 018import java.util.Iterator; 019import java.util.List; 020import java.util.Map; 021import java.util.Map.Entry; 022 023/** 024 * Datatype is an abstract class that defines datatype characteristics and APIs for a data type. 025 * <p> 026 * A datatype has four basic characteristics: class, size, byte order and sign. These 027 * characteristics are defined in the 028 * <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a>. 029 * <p> 030 * These characteristics apply to all the sub-classes. The sub-classes may have different ways to 031 * describe a datatype. We here define the <strong> native datatype</strong> to the datatype used by 032 * the sub-class. For example, H5Datatype uses a datatype identifier (hid_t) to specify a datatype. 033 * NC2Datatype uses ucar.nc2.DataType object to describe its datatype. "Native" here is different 034 * from the "native" definition in the HDF5 library. 035 * <p> 036 * Two functions, createNative() and fromNative(), are defined to convert the general 037 * characteristics to/from the native datatype. Sub-classes must implement these functions so that 038 * the conversion will be done correctly. The values of the CLASS member are not identical to HDF5 039 * values for a datatype class. 040 * <p> 041 * 042 * @version 1.1 9/4/2007 043 * @author Peter X. Cao 044 */ 045public abstract class Datatype extends HObject implements MetaDataContainer { 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="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 058 */ 059 public static final int CLASS_NO_CLASS = -1; 060 061 /** 062 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 063 */ 064 public static final int CLASS_INTEGER = 0; 065 066 /** 067 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 068 */ 069 public static final int CLASS_FLOAT = 1; 070 071 /** 072 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 073 */ 074 public static final int CLASS_CHAR = 2; 075 076 /** 077 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 078 */ 079 public static final int CLASS_STRING = 3; 080 081 /** 082 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 083 */ 084 public static final int CLASS_BITFIELD = 4; 085 086 /** 087 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 088 */ 089 public static final int CLASS_OPAQUE = 5; 090 091 /** 092 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 093 */ 094 public static final int CLASS_COMPOUND = 6; 095 096 /** 097 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 098 */ 099 public static final int CLASS_REFERENCE = 7; 100 101 /** 102 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 103 */ 104 public static final int CLASS_ENUM = 8; 105 106 /** 107 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 108 */ 109 public static final int CLASS_VLEN = 9; 110 111 /** 112 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 113 */ 114 public static final int CLASS_ARRAY = 10; 115 116 /** 117 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 118 */ 119 public static final int CLASS_TIME = 11; 120 121 /** 122 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 123 */ 124 public static final int ORDER_LE = 0; 125 126 /** 127 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 128 */ 129 public static final int ORDER_BE = 1; 130 131 /** 132 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 133 */ 134 public static final int ORDER_VAX = 2; 135 136 /** 137 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 138 */ 139 public static final int ORDER_NONE = 3; 140 141 /** 142 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 143 */ 144 public static final int SIGN_NONE = 0; 145 146 /** 147 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 148 */ 149 public static final int SIGN_2 = 1; 150 151 /** 152 * See <a href="https://support.hdfgroup.org/HDF5/doc/UG/HDF5_Users_Guide-Responsive%20HTML5/index.html">HDF5 User's Guide</a> 153 */ 154 public static final int NSGN = 2; 155 156 protected String datatypeDescription = null; 157 158 /** 159 * The class of the datatype. 160 */ 161 protected int datatypeClass; 162 163 /** 164 * The size (in bytes) of the datatype. 165 */ 166 protected long datatypeSize; 167 168 /** 169 * The byte order of the datatype. Valid values are ORDER_LE, ORDER_BE, and 170 * ORDER_VAX. 171 */ 172 protected int datatypeOrder; 173 174 /** 175 * The sign of the datatype. 176 */ 177 protected int datatypeSign; 178 179 /** 180 * The base datatype of this datatype (null if this datatype is atomic). 181 */ 182 protected Datatype baseType; 183 184 /** 185 * The dimensions of the ARRAY element of an ARRAY datatype. 186 */ 187 protected long[] arrayDims; 188 189 /** 190 * Determines whether this datatype is a variable-length type. 191 */ 192 protected boolean is_VLEN = false; 193 protected boolean is_variable_str = false; 194 195 /** 196 * The (name, value) pairs of enum members. 197 */ 198 protected Map<String, String> enumMembers; 199 200 /** 201 * The list of names of members of a compound Datatype. 202 */ 203 protected List<String> compoundMemberNames; 204 205 /** 206 * The list of types of members of a compound Datatype. 207 */ 208 protected List<Datatype> compoundMemberTypes; 209 210 /** 211 * The list of offsets of members of a compound Datatype. 212 */ 213 protected List<Long> compoundMemberOffsets; 214 215 /** 216 * Constructs a named datatype with a given file, name and path. 217 * 218 * @param theFile 219 * the HDF file. 220 * @param typeName 221 * the name of the datatype, e.g "12-bit Integer". 222 * @param typePath 223 * the full group path of the datatype, e.g. "/datatypes/". 224 */ 225 public Datatype(FileFormat theFile, String typeName, String typePath) { 226 this(theFile, typeName, typePath, 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 typeName 236 * the name of the datatype, e.g "12-bit Integer". 237 * @param typePath 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 typeName, String typePath, long[] oid) { 244 super(theFile, typeName, typePath, 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 this(tclass, tsize, torder, tsign, tbase, null); 313 } 314 315 /** 316 * Constructs a Datatype with specified class, size, byte order and sign. 317 * <p> 318 * The following is a list of a few example of H5Datatype. 319 * <ol> 320 * <li>to create unsigned native integer<br> 321 * H5Datatype type = new H5Dataype(CLASS_INTEGER, NATIVE, NATIVE, SIGN_NONE); 322 * <li>to create 16-bit signed integer with big endian<br> 323 * H5Datatype type = new H5Dataype(CLASS_INTEGER, 2, ORDER_BE, NATIVE); 324 * <li>to create native float<br> 325 * H5Datatype type = new H5Dataype(CLASS_FLOAT, NATIVE, NATIVE, -1); 326 * <li>to create 64-bit double<br> 327 * H5Datatype type = new H5Dataype(CLASS_FLOAT, 8, NATIVE, -1); 328 * </ol> 329 * 330 * @param tclass 331 * the class of the datatype, e.g. CLASS_INTEGER, CLASS_FLOAT and etc. 332 * @param tsize 333 * the size of the datatype in bytes, e.g. for a 32-bit integer, the size is 4. 334 * @param torder 335 * the byte order of the datatype. Valid values are ORDER_LE, ORDER_BE, ORDER_VAX and 336 * ORDER_NONE 337 * @param tsign 338 * the sign of the datatype. Valid values are SIGN_NONE, SIGN_2 and MSGN 339 * @param tbase 340 * the base datatype of the new datatype 341 * @param pbase 342 * the parent datatype of the new datatype 343 */ 344 public Datatype(int tclass, int tsize, int torder, int tsign, Datatype tbase, Datatype pbase) { 345 datatypeClass = tclass; 346 datatypeSize = tsize; 347 datatypeOrder = torder; 348 datatypeSign = tsign; 349 enumMembers = null; 350 baseType = tbase; 351 arrayDims = null; 352 is_variable_str = (datatypeClass == Datatype.CLASS_STRING) && (tsize < 0); 353 is_VLEN = (datatypeClass == Datatype.CLASS_VLEN) || is_variable_str; 354 355 log.trace("datatypeClass={} datatypeSize={} datatypeOrder={} datatypeSign={} baseType={}", 356 datatypeClass, datatypeSize, datatypeOrder, datatypeSign, baseType); 357 } 358 359 /** 360 * Constructs a Datatype with a given native datatype identifier. 361 * <p> 362 * For example, if the datatype identifier is a 32-bit unsigned integer created from HDF5, 363 * 364 * <pre> 365 * long tid = H5.H5Tcopy(HDF5Constants.H5T_NATIVE_UNINT32); 366 * Datatype dtype = new Datatype(tid); 367 * </pre> 368 * 369 * will construct a datatype equivalent to new Datatype(CLASS_INTEGER, 4, NATIVE, SIGN_NONE); 370 * 371 * @see #fromNative(long tid) 372 * @param tid 373 * the native datatype identifier. 374 */ 375 public Datatype(long tid) { 376 this(tid, null); 377 } 378 379 /** 380 * Constructs a Datatype with a given native datatype identifier. 381 * <p> 382 * For example, if the datatype identifier is a 32-bit unsigned integer created 383 * from HDF5, 384 * 385 * <pre> 386 * long tid = H5.H5Tcopy(HDF5Constants.H5T_NATIVE_UNINT32); 387 * Datatype dtype = new Datatype(tid); 388 * </pre> 389 * 390 * will construct a datatype equivalent to new Datatype(CLASS_INTEGER, 4, 391 * NATIVE, SIGN_NONE); 392 * 393 * @see #fromNative(long tid) 394 * @param tid 395 * the native datatype identifier. 396 * @param pbase 397 * the parent datatype of the new datatype 398 */ 399 public Datatype(long tid, Datatype pbase) { 400 this(CLASS_NO_CLASS, NATIVE, NATIVE, NATIVE, null, pbase); 401 } 402 403 /** 404 * Opens access to this named datatype. Sub-classes must replace this default implementation. For 405 * example, in H5Datatype, open() function H5.H5Topen(loc_id, name) to get the datatype identifier. 406 * 407 * @return the datatype identifier if successful; otherwise returns negative value. 408 */ 409 @Override 410 public long open() { 411 return -1; 412 } 413 414 /** 415 * Closes a datatype identifier. 416 * <p> 417 * Sub-classes must replace this default implementation. 418 * 419 * @param id 420 * the datatype identifier to close. 421 */ 422 @Override 423 public abstract void close(long id); 424 425 /** 426 * Returns the class of the datatype. Valid values are: 427 * <ul> 428 * <li>CLASS_NO_CLASS 429 * <li>CLASS_INTEGER 430 * <li>CLASS_FLOAT 431 * <li>CLASS_CHAR 432 * <li>CLASS_STRING 433 * <li>CLASS_BITFIELD 434 * <li>CLASS_OPAQUE 435 * <li>CLASS_COMPOUND 436 * <li>CLASS_REFERENCE 437 * <li>CLASS_ENUM 438 * <li>CLASS_VLEN 439 * <li>CLASS_ARRAY 440 * </ul> 441 * 442 * @return the class of the datatype. 443 */ 444 public int getDatatypeClass() { 445 return datatypeClass; 446 } 447 448 /** 449 * Returns the size of the datatype in bytes. For example, for a 32-bit 450 * integer, the size is 4 (bytes). 451 * 452 * @return the size of the datatype. 453 */ 454 public long getDatatypeSize() { 455 return datatypeSize; 456 } 457 458 /** 459 * Returns the byte order of the datatype. Valid values are 460 * <ul> 461 * <li>ORDER_LE 462 * <li>ORDER_BE 463 * <li>ORDER_VAX 464 * <li>ORDER_NONE 465 * </ul> 466 * 467 * @return the byte order of the datatype. 468 */ 469 public int getDatatypeOrder() { 470 return datatypeOrder; 471 } 472 473 /** 474 * Returns the sign (SIGN_NONE, SIGN_2 or NSGN) of an integer datatype. 475 * 476 * @return the sign of the datatype. 477 */ 478 public int getDatatypeSign() { 479 return datatypeSign; 480 } 481 482 /** 483 * Returns the datatype of the elements for this datatype. 484 * <p> 485 * For example, in a dataset of type ARRAY of integer, the datatype of the dataset is ARRAY. The 486 * datatype of the base type is integer. 487 * 488 * @return the datatype of the contained datatype. 489 */ 490 public Datatype getDatatypeBase() { 491 return baseType; 492 } 493 494 /** 495 * Sets the (name, value) pairs of enum members for enum datatype. 496 * <p> 497 * For Example, 498 * <dl> 499 * <dt>setEnumMembers("lowTemp=-40, highTemp=90")</dt> 500 * <dd>sets the value of enum member lowTemp to -40 and highTemp to 90.</dd> 501 * <dt>setEnumMembers("lowTemp, highTemp")</dt> 502 * <dd>sets enum members to defaults, i.e. lowTemp=0 and highTemp=1</dd> 503 * <dt>setEnumMembers("lowTemp=10, highTemp")</dt> 504 * <dd>sets enum member lowTemp to 10 and highTemp to 11.</dd> 505 * </dl> 506 * 507 * @param enumStr 508 * the (name, value) pairs of enum members 509 */ 510 public final void setEnumMembers(String enumStr) { 511 log.trace("setEnumMembers: is_enum enum_members={}", enumStr); 512 enumMembers = new HashMap<>(); 513 String[] entries = enumStr.split(","); 514 for (String entry : entries) { 515 String[] keyValue = entry.split("="); 516 enumMembers.put(keyValue[1].trim(), keyValue[0].trim()); 517 log.trace("setEnumMembers: is_enum value={} name={}", keyValue[1].trim(), keyValue[0].trim()); 518 } 519 } 520 521 /** 522 * Returns the Map<String,String> pairs of enum members for enum datatype. 523 * 524 * @return enumStr Map<String,String%gt; pairs of enum members 525 */ 526 public final Map<String, String> getEnumMembers() { 527 if (enumMembers == null) { 528 enumMembers = new HashMap<>(); 529 enumMembers.put("1", "0"); 530 enumMembers.put("2", "1"); 531 } 532 533 return enumMembers; 534 } 535 536 /** 537 * Returns the HashMap pairs of enum members for enum datatype. 538 * <p> 539 * For Example, 540 * <dl> 541 * <dt>getEnumMembersAsString()</dt> 542 * <dd>returns "lowTemp=10, highTemp=40"</dd> 543 * </dl> 544 * 545 * @return enumStr the (name, value) pairs of enum members 546 */ 547 @SuppressWarnings("rawtypes") 548 public final String getEnumMembersAsString() { 549 if (enumMembers == null) { 550 enumMembers = new HashMap<>(); 551 enumMembers.put("1", "0"); 552 enumMembers.put("2", "1"); 553 } 554 555 String enumStr = new String(); 556 Iterator<Entry<String, String>> entries = enumMembers.entrySet().iterator(); 557 int i = enumMembers.size(); 558 while (entries.hasNext()) { 559 Entry thisEntry = entries.next(); 560 String memstr = (String) thisEntry.getKey(); 561 String memname = (String) thisEntry.getValue(); 562 enumStr += memname + "=" + memstr; 563 i--; 564 if (i > 0) 565 enumStr += ", "; 566 } 567 return enumStr; 568 } 569 570 /** 571 * Returns the dimensions of an Array Datatype. 572 * 573 * @return dims the dimensions of the Array Datatype 574 */ 575 public final long[] getArrayDims() { 576 return arrayDims; 577 } 578 579 public final List<String> getCompoundMemberNames() { 580 return compoundMemberNames; 581 } 582 583 public final List<Datatype> getCompoundMemberTypes() { 584 return compoundMemberTypes; 585 } 586 587 /** 588 * Converts the datatype object to a native datatype. 589 * 590 * Subclasses must implement it so that this datatype will be converted accordingly. Use close() to 591 * close the native identifier; otherwise, the datatype will be left open. 592 * <p> 593 * For example, a HDF5 datatype created from<br> 594 * 595 * <pre> 596 * H5Dataype dtype = new H5Datatype(CLASS_INTEGER, 4, NATIVE, SIGN_NONE); 597 * int tid = dtype.createNative(); 598 * </pre> 599 * 600 * The "tid" will be the HDF5 datatype id of a 64-bit unsigned integer, which is equivalent to 601 * 602 * <pre> 603 * int tid = H5.H5Tcopy(HDF5Constants.H5T_NATIVE_UNINT32); 604 * </pre> 605 * 606 * @return the identifier of the native datatype. 607 */ 608 public abstract long createNative(); 609 610 /** 611 * Set datatype characteristics (class, size, byte order and sign) from a given datatype identifier. 612 * <p> 613 * Sub-classes must implement it so that this datatype will be converted accordingly. 614 * <p> 615 * For example, if the type identifier is a 64-bit unsigned integer created from HDF5, 616 * 617 * <pre> 618 * H5Datatype dtype = new H5Datatype(); 619 * dtype.fromNative(HDF5Constants.H5T_NATIVE_UNINT32); 620 * </pre> 621 * 622 * Where dtype is equivalent to <br> 623 * new H5Datatype(CLASS_INTEGER, 4, NATIVE, SIGN_NONE); 624 * 625 * @param nativeID 626 * the datatype identifier. 627 */ 628 public abstract void fromNative(long nativeID); 629 630 /** 631 * Returns a short text description of this datatype. 632 * 633 * @return a short text description of this datatype 634 */ 635 public String getDescription() { 636 log.trace("getDescription(): start"); 637 638 if (datatypeDescription != null) { 639 log.trace("getDescription(): finish"); 640 return datatypeDescription; 641 } 642 643 String description = null; 644 645 switch (datatypeClass) { 646 case CLASS_CHAR: 647 description = "8-bit " + (isUnsigned() ? "unsigned " : "") + "integer"; 648 break; 649 case CLASS_INTEGER: 650 description = String.valueOf(datatypeSize * 8) + "-bit " + (isUnsigned() ? "unsigned " : "") + "integer"; 651 break; 652 case CLASS_FLOAT: 653 description = String.valueOf(datatypeSize * 8) + "-bit floating-point"; 654 break; 655 case CLASS_STRING: 656 description = "String"; 657 break; 658 case CLASS_REFERENCE: 659 description = "Object reference"; 660 break; 661 case CLASS_BITFIELD: 662 description = String.valueOf(datatypeSize * 8) + "-bit bitfield"; 663 break; 664 case CLASS_ENUM: 665 description = String.valueOf(datatypeSize * 8) + "-bit enum"; 666 break; 667 case CLASS_ARRAY: 668 description = "Array"; 669 break; 670 case CLASS_COMPOUND: 671 description = "Compound"; 672 break; 673 case CLASS_VLEN: 674 description = "Variable-length"; 675 break; 676 default: 677 description = "Unknown"; 678 break; 679 } 680 681 if (baseType != null) { 682 description += " of " + baseType.getDescription(); 683 } 684 685 log.trace("getDescription(): finish"); 686 return description; 687 } 688 689 /** 690 * Checks if this datatype is unsigned. 691 * 692 * @return true if the datatype is unsigned; 693 * otherwise, returns false. 694 */ 695 public boolean isUnsigned() { 696 if (baseType != null) 697 return baseType.isUnsigned(); 698 else { 699 if (isCompound()) { 700 if ((compoundMemberTypes != null) && (compoundMemberTypes.size() > 0)) { 701 boolean all_members_unsigned = true; 702 703 Iterator<Datatype> cmpd_type_list_it = compoundMemberTypes.iterator(); 704 while (cmpd_type_list_it.hasNext()) { 705 Datatype next = cmpd_type_list_it.next(); 706 707 all_members_unsigned = all_members_unsigned && next.isUnsigned(); 708 } 709 710 return all_members_unsigned; 711 } 712 else { 713 log.debug("isUnsigned(): compoundMemberTypes is null"); 714 return false; 715 } 716 } 717 else { 718 return (datatypeSign == Datatype.SIGN_NONE); 719 } 720 } 721 } 722 723 public abstract boolean isText(); 724 725 /** 726 * Checks if this datatype is an integer type. 727 * 728 * @return true if the datatype is integer; false otherwise 729 */ 730 public boolean isInteger() { 731 return (datatypeClass == Datatype.CLASS_INTEGER); 732 } 733 734 /** 735 * Checks if this datatype is a floating-point type. 736 * 737 * @return true if the datatype is floating-point; false otherwise 738 */ 739 public boolean isFloat() { 740 return (datatypeClass == Datatype.CLASS_FLOAT); 741 } 742 743 /** 744 * Checks if this datatype is a variable-length string type. 745 * 746 * @return true if the datatype is variable-length string; false otherwise 747 */ 748 public boolean isVarStr() { 749 return is_variable_str; 750 } 751 752 /** 753 * Checks if this datatype is a variable-length type. 754 * 755 * @return true if the datatype is variable-length; false otherwise 756 */ 757 public boolean isVLEN() { 758 return is_VLEN; 759 } 760 761 /** 762 * Checks if this datatype is an compound type. 763 * 764 * @return true if the datatype is compound; false otherwise 765 */ 766 public boolean isCompound() { 767 return (datatypeClass == Datatype.CLASS_COMPOUND); 768 } 769 770 /** 771 * Checks if this datatype is an array type. 772 * 773 * @return true if the datatype is array; false otherwise 774 */ 775 public boolean isArray() { 776 return (datatypeClass == Datatype.CLASS_ARRAY); 777 } 778 779 /** 780 * Checks if this datatype is a string type. 781 * 782 * @return true if the datatype is string; false otherwise 783 */ 784 public boolean isString() { 785 return (datatypeClass == Datatype.CLASS_STRING); 786 } 787 788 /** 789 * Checks if this datatype is a character type. 790 * 791 * @return true if the datatype is character; false otherwise 792 */ 793 public boolean isChar() { 794 return (datatypeClass == Datatype.CLASS_CHAR); 795 } 796 797 /** 798 * Checks if this datatype is a reference type. 799 * 800 * @return true if the datatype is reference; false otherwise 801 */ 802 public boolean isRef() { 803 return (datatypeClass == Datatype.CLASS_REFERENCE); 804 } 805 806 /** 807 * Checks if this datatype is a enum type. 808 * 809 * @return true if the datatype is enum; false otherwise 810 */ 811 public boolean isEnum() { 812 return (datatypeClass == Datatype.CLASS_ENUM); 813 } 814 815 /** 816 * Checks if this datatype is a opaque type. 817 * 818 * @return true if the datatype is opaque; false otherwise 819 */ 820 public boolean isOpaque() { 821 return (datatypeClass == Datatype.CLASS_OPAQUE); 822 } 823 824 /** 825 * Checks if this datatype is a bitfield type. 826 * 827 * @return true if the datatype is bitfield; false otherwise 828 */ 829 public boolean isBitField() { 830 return (datatypeClass == Datatype.CLASS_BITFIELD); 831 } 832 833 /* 834 * (non-Javadoc) 835 * 836 * @see hdf.object.DataFormat#getMetadata() 837 */ 838 @Override 839 @SuppressWarnings("rawtypes") 840 public List getMetadata() throws Exception { 841 return null; 842 } 843 844 /* 845 * (non-Javadoc) 846 * 847 * @see hdf.object.DataFormat#writeMetadata(java.lang.Object) 848 */ 849 @Override 850 public void writeMetadata(Object info) throws Exception { 851 throw new UnsupportedOperationException("Unsupported operation. Subclasses must implement Datatype:writeMetadata."); 852 } 853 854 /* 855 * (non-Javadoc) 856 * 857 * @see hdf.object.DataFormat#removeMetadata(java.lang.Object) 858 */ 859 @Override 860 public void removeMetadata(Object info) throws Exception { 861 throw new UnsupportedOperationException("Unsupported operation. Subclasses must implement Datatype:removeMetadata."); 862 } 863 864 /* 865 * (non-Javadoc) 866 * 867 * @see hdf.object.DataFormat#updateMetadata(java.lang.Object) 868 */ 869 @Override 870 public void updateMetadata(Object info) throws Exception { 871 throw new UnsupportedOperationException("Unsupported operation. Subclasses must implement Datatype:updateMetadata."); 872 } 873 874 @Override 875 public String toString() { 876 return getDescription(); 877 } 878}