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