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