1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926
|
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<title>Enumeration Data Types in the Data Type Interface (H5T)</title>
</head>
<body bgcolor="#FFFFFF">
<hr>
<center>
<table border=0 width=98%>
<tr><td valign=top align=left>
<a href="H5.intro.html">Introduction to HDF5</a> <br>
<a href="RM_H5Front.html">HDF5 Reference Manual</a> <br>
<a href="index.html">Other HDF5 documents and links</a> <br>
<!--
<a href="Glossary.html">Glossary</a><br>
-->
</td>
<td valign=top align=right>
And in this document, the
<a href="H5.user.html">HDF5 User's Guide</a>:
<a href="Files.html">Files</a>
<br>
<a href="Datasets.html">Datasets</a>
<a href="Datatypes.html">Data Types</a>
<a href="Dataspaces.html">Dataspaces</a>
<a href="Groups.html">Groups</a>
<a href="References.html">References</a>
<br>
<a href="Attributes.html">Attributes</a>
<a href="Properties.html">Property Lists</a>
<a href="Errors.html">Error Handling</a>
<a href="Filters.html">Filters</a>
<a href="Caching.html">Caching</a>
<br>
<a href="Chunking.html">Chunking</a>
<a href="Debugging.html">Debugging</a>
<a href="Environment.html">Environment</a>
<a href="ddl.html">DDL</a>
<a href="Ragged.html">Ragged Arrays</a>
<!--
<hr>
And in this document, the
<a href="H5.user.html">HDF5 User's Guide</a>:
<a href="Attributes.html">H5A</a>
<a href="Datasets.html">H5D</a>
<a href="Errors.html">H5E</a>
<a href="Files.html">H5F</a>
<a href="Groups.html">H5G</a>
<a href="Properties.html">H5P</a>
<a href="References.html">H5R & H5I</a>
<a href="Ragged.html">H5RA</a>
<a href="Dataspaces.html">H5S</a>
<a href="Datatypes.html">H5T</a>
<a href="Filters.html">H5Z</a>
<a href="Caching.html">Caching</a>
<a href="Chunking.html">Chunking</a>
<a href="Debugging.html">Debugging</a>
<a href="Environment.html">Environment</a>
<a href="ddl.html">DDL</a>
-->
</td></tr>
</table>
</center>
<hr>
<h1>The Data Type Interface (H5T) <font size=-1><i>(contitnued)</i></font></h1>
<p align=right><font size=-1><i>
(Return to <a href="Datatypes.html#Datatypes_Enum">Data Types Interface (H5T)</a>.)
</font></i>
<h2>7. Enumeration Data Types</h2>
<h3>7.1. Introduction</h2>
<p>An HDF enumeration data type is a 1:1 mapping between a set of
symbols and a set of integer values, and an order is imposed on
the symbols by their integer values. The symbols are passed
between the application and library as character strings and all
the values for a particular enumeration type are of the same
integer type, which is not necessarily a native type.
<h3>7.2. Creation</h2>
<p>Creation of an enumeration data type resembles creation of a
compound data type: first an empty enumeration type is created,
then members are added to the type, then the type is optionally
locked.
<dl>
<dt><code>hid_t H5Tcreate(H5T_class_t <em>type_class</em>,
size_t <em>size</em>)</code>
<dd>This function creates a new empty enumeration data type based
on a native signed integer type. The first argument is the
constant <code>H5T_ENUM</code> and the second argument is the
size in bytes of the native integer on which the enumeration
type is based. If the architecture does not support a native
signed integer of the specified size then an error is
returned.
<pre>
/* Based on a native signed short */
hid_t hdf_en_colors = H5Tcreate(H5T_ENUM, sizeof(short));</pre>
<dt><code>hid_t H5Tenum_create(hid_t <em>base</em>)</code>
<dd>This function creates a new empty enumeration data type based
on some integer data type <em>base</em> and is a
generalization of the <code>H5Tcreate()</code> function. This
function is useful when creating an enumeration type based on
some non-native integer data type, but it can be used for
native types as well.
<pre>
/* Based on a native unsigned short */
hid_t hdf_en_colors_1 = H5Tenum_create(H5T_NATIVE_USHORT);
/* Based on a MIPS 16-bit unsigned integer */
hid_t hdf_en_colors_2 = H5Tenum_create(H5T_MIPS_UINT16);
/* Based on a big-endian 16-bit unsigned integer */
hid_t hdf_en_colors_3 = H5Tenum_create(H5T_STD_U16BE);</pre>
<dt><code>herr_t H5Tenum_insert(hid_t <em>etype</em>, const char
*<em>symbol</em>, void *<em>value</em>)</code>
<dd>Members are inserted into the enumeration data type
<em>etype</em> with this function. Each member has a symbolic
name <em>symbol</em> and some integer representation
<em>value</em>. The <em>value</em> argument must point to a value
of the same data type as specified when the enumeration type
was created. The order of member insertion is not important
but all symbol names and values must be unique within a
particular enumeration type.
<pre>
short val;
H5Tenum_insert(hdf_en_colors, "RED", (val=0,&val));
H5Tenum_insert(hdf_en_colors, "GREEN", (val=1,&val));
H5Tenum_insert(hdf_en_colors, "BLUE", (val=2,&val));
H5Tenum_insert(hdf_en_colors, "WHITE", (val=3,&val));
H5Tenum_insert(hdf_en_colors, "BLACK", (val=4,&val));</pre>
<dt><code>herr_t H5Tlock(hid_t <em>etype</em>)</code>
<dd>This function locks a data type so it cannot be modified or
freed unless the entire HDF5 library is closed. Its use is
completely optional but using it on an application data type
makes that data type act like a predefined data type.
<pre>
H5Tlock(hdf_en_colors);</pre>
</dl>
<h3>7.3. Integer Operations</h2>
<p>Because an enumeration data type is derived from an integer
data type, any operation which can be performed on integer data
types can also be performed on enumeration data types. This
includes:
<p>
<center>
<table>
<tr>
<td><code>H5Topen()</code></td>
<td><code>H5Tcreate()</code></td>
<td><code>H5Tcopy()</code></td>
<td><code>H5Tclose()</code></td>
</tr><tr>
<td><code>H5Tequal()</code></td>
<td><code>H5Tlock()</code></td>
<td><code>H5Tcommit()</code></td>
<td><code>H5Tcommitted()</code></td>
</tr><tr>
<td><code>H5Tget_class()</code></td>
<td><code>H5Tget_size()</code></td>
<td><code>H5Tget_order()</code></td>
<td><code>H5Tget_pad()</code></td>
</tr><tr>
<td><code>H5Tget_precision()</code></td>
<td><code>H5Tget_offset()</code></td>
<td><code>H5Tget_sign()</code></td>
<td><code>H5Tset_size()</code></td>
</tr><tr>
<td><code>H5Tset_order()</code></td>
<td><code>H5Tset_precision()</code></td>
<td><code>H5Tset_offset()</code></td>
<td><code>H5Tset_pad()</code></td>
</tr><tr>
<td><code>H5Tset_sign()</code></td>
</tr>
</table>
</center>
<p>In addition, the new function <code>H5Tget_super()</code> will
be defined for all data types that are derived from existing
types (currently just enumeration types).
<dl>
<dt><code>hid_t H5Tget_super(hid_t <em>type</em>)</code>
<dd>Return the data type from which <em>type</em> is
derived. When <em>type</em> is an enumeration data type then
the returned value will be an integer data type but not
necessarily a native type. One use of this function would be
to create a new enumeration type based on the same underlying
integer type and values but with possibly different symbols.
<pre>
hid_t itype = H5Tget_super(hdf_en_colors);
hid_t hdf_fr_colors = H5Tenum_create(itype);
H5Tclose(itype);
short val;
H5Tenum_insert(hdf_fr_colors, "ouge", (val=0,&val));
H5Tenum_insert(hdf_fr_colors, "vert", (val=1,&val));
H5Tenum_insert(hdf_fr_colors, "bleu", (val=2,&val));
H5Tenum_insert(hdf_fr_colors, "blanc", (val=3,&val));
H5Tenum_insert(hdf_fr_colors, "noir", (val=4,&val));
H5Tlock(hdf_fr_colors);</pre>
</dl>
<h3>7.4. Type Functions</h2>
<p>A small set of functions is available for querying properties
of an enumeration type. These functions are likely to be used
by browsers to display data type information.
<dl>
<dt><code>int H5Tget_nmembers(hid_t <em>etype</em>)</code>
<dd>When given an enumeration data type <em>etype</em> this
function returns the number of members defined for that
type. This function is already implemented for compound data
types.
<br><br>
<dt><code>char *H5Tget_member_name(hid_t <em>etype</em>, unsigned
<em>membno</em>)</code>
<dd>Given an enumeration data type <em>etype</em> this function
returns the symbol name for the member indexed by
<em>membno</em>. Members are numbered from zero to
<em>N</em>-1 where <em>N</em> is the return value from
<code>H5Tget_nmembers()</code>. The members are stored in no
particular order. This function is already implemented for
compound data types. If an error occurs then the null pointer
is returned. The return value should be freed by calling
<code>free()</code>.
<br><br>
<dt><code>herr_t H5Tget_member_value(hid_t <em>etype</em>, unsigned
<em>membno</em>, void *<em>value</em>/*out*/)</code>
<dd>Given an enumeration data type <em>etype</em> this function
returns the value associated with the member indexed by
<em>membno</em> (as described for
<code>H5Tget_member_name()</code>). The value returned
is in the domain of the underlying integer
data type which is often a native integer type. The
application should ensure that the memory pointed to by
<em>value</em> is large enough to contain the result (the size
can be obtained by calling <code>H5Tget_size()</code> on
either the enumeration type or the underlying integer type
when the type is not known by the C compiler.
<pre>
int n = H5Tget_nmembers(hdf_en_colors);
unsigned u;
for (u=0; u<(unsigned)n; u++) {
char *symbol = H5Tget_member_name(hdf_en_colors, u);
short val;
H5Tget_member_value(hdf_en_colors, u, &val);
printf("#%u %20s = %d\n", u, symbol, val);
free(symbol);
}</pre>
<p>
Output:
<pre>
#0 BLACK = 4
#1 BLUE = 2
#2 GREEN = 1
#3 RED = 0
#4 WHITE = 3</pre>
</dl>
<h3>7.5. Data Functions</h2>
<p>In addition to querying about the enumeration type properties,
an application may want to make queries about enumerated
data. These functions perform efficient mappings between symbol
names and values.
<dl>
<dt><code>herr_t H5Tenum_valueof(hid_t <em>etype</em>, const char
*<em>symbol</em>, void *<em>value</em>/*out*/)</code>
<dd>Given an enumeration data type <em>etype</em> this function
returns through <em>value</em> the bit pattern associated with
the symbol name <em>symbol</em>. The <em>value</em> argument
should point to memory which is large enough to hold the result,
which is returned as the underlying integer data type specified
when the enumeration type was created, often a native integer
type.
<br><br>
<dt><code>herr_t H5Tenum_nameof(hid_t <em>etype</em>, void
*<em>value</em>, char *<em>symbol</em>, size_t
<em>size</em>)</code>
<dd>This function translates a bit pattern pointed to by
<em>value</em> to a symbol name according to the mapping
defined in the enumeration data type <em>etype</em> and stores
at most <em>size</em> characters of that name (counting the
null terminator) to the <em>symbol</em> buffer. If the name is
longer than the result buffer then the result is not null
terminated and the function returns failure. If <em>value</em>
points to a bit pattern which is not in the domain of the
enumeration type then the first byte of the <em>symbol</em>
buffer is set to zero and the function fails.
<pre>
short data[1000] = {4, 2, 0, 0, 5, 1, ...};
int i;
char symbol[32];
for (i=0; i<1000; i++) {
if (H5Tenum_nameof(hdf_en_colors, data+i, symbol,
sizeof symbol))<0) {
if (symbol[0]) {
strcpy(symbol+sizeof(symbol)-4, "...");
} else {
strcpy(symbol, "UNKNOWN");
}
}
printf("%d %s\n", data[i], symbol);
}
printf("}\n");</pre>
<p>
Output:
<pre>
4 BLACK
2 BLUE
0 RED
0 RED
5 UNKNOWN
1 GREEN
...</pre>
</dl>
<h3>7.6. Conversion</h2>
<p>Enumerated data can be converted from one type to another
provided the destination enumeration type contains all the
symbols of the source enumeration type. The conversion operates
by matching up the symbol names of the source and destination
enumeration types to build a mapping from source value to
destination value. For instance, if we are translating from an
enumeration type that defines a sequence of integers as the
values for the colors to a type that defines a different bit for
each color then the mapping might look like this:
<p><img src="EnumMap.gif" alt="Enumeration Mapping">
<p>That is, a source value of <code>2</code> which corresponds to
<code>BLUE</code> would be mapped to <code>0x0004</code>. The
following code snippet builds the second data type, then
converts a raw data array from one data type to another, and
then prints the result.
<pre>
/* Create a new enumeration type */
short val;
hid_t bits = H5Tcreate(H5T_ENUM, sizeof val);
H5Tenum_insert(bits, "RED", (val=0x0001,&val));
H5Tenum_insert(bits, "GREEN", (val=0x0002,&val));
H5Tenum_insert(bits, "BLUE", (val=0x0004,&val));
H5Tenum_insert(bits, "WHITE", (val=0x0008,&val));
H5Tenum_insert(bits, "BLACK", (val=0x0010,&val));
/* The data */
short data[6] = {1, 4, 2, 0, 3, 5};
/* Convert the data from one type to another */
H5Tconvert(hdf_en_colors, bits, 5, data, NULL);
/* Print the data */
for (i=0; i<6; i++) {
printf("0x%04x\n", (unsigned)(data[i]));
}</pre>
<p>
Output:
<pre>
0x0002
0x0010
0x0004
0x0001
0x0008
0xffff</pre>
<p>If the source data stream contains values which are not in the
domain of the conversion map then an overflow exception is
raised within the library, causing the application defined
overflow handler to be invoked (see
<code>H5Tset_overflow()</code>). If no overflow handler is
defined then all bits of the destination value will be set.
<p>The HDF library will not provide conversions between enumerated
data and integers although the application is free to do so
(this is a policy we apply to all classes of HDF data
types). However, since enumeration types are derived from
integer types it is permissible to treat enumerated data as
integers and perform integer conversions in that context.
<h3>7.7. Symbol Order</h2>
<p>Symbol order is determined by the integer values associated
with each symbol. When the integer data type is a native type,
testing the relative order of two symbols is an easy process:
simply compare the values of the symbols. If only the symbol
names are available then the values must first be determined by
calling <code>H5Tenum_valueof()</code>.
<pre>
short val1, val2;
H5Tenum_valueof(hdf_en_colors, "WHITE", &val1);
H5Tenum_valueof(hdf_en_colors, "BLACK", &val2);
if (val1 < val2) ...</pre>
<p>When the underlying integer data type is not a native type then
the easiest way to compare symbols is to first create a similar
enumeration type that contains all the same symbols but has a
native integer type (HDF type conversion features can be used to
convert the non-native values to native values). Once we have a
native type we can compare symbol order as just described. If
<code>foreign</code> is some non-native enumeration type then a
native type can be created as follows:
<pre>
int n = H5Tget_nmembers(foreign);
hid_t itype = H5Tget_super(foreign);
void *val = malloc(n * MAX(H5Tget_size(itype), sizeof(int)));
char *name = malloc(n * sizeof(char*));
unsigned u;
/* Get foreign type information */
for (u=0; u<(unsigned)n; u++) {
name[u] = H5Tget_member_name(foreign, u);
H5Tget_member_value(foreign, u,
(char*)val+u*H5Tget_size(foreign));
}
/* Convert integer values to new type */
H5Tconvert(itype, H5T_NATIVE_INT, n, val, NULL);
/* Build a native type */
hid_t native = H5Tenum_create(H5T_NATIVE_INT);
for (i=0; i<n; i++) {
H5Tenum_insert(native, name[i], ((int*)val)[i]);
free(name[i]);
}
free(name);
free(val);</pre>
<p>It is also possible to convert enumerated data to a new type
that has a different order defined for the symbols. For
instance, we can define a new type, <code>reverse</code> that
defines the same five colors but in the reverse order.
<pre>
short val;
int i;
char sym[8];
short data[5] = {0, 1, 2, 3, 4};
hid_t reverse = H5Tenum_create(H5T_NATIVE_SHORT);
H5Tenum_insert(reverse, "BLACK", (val=0,&val));
H5Tenum_insert(reverse, "WHITE", (val=1,&val));
H5Tenum_insert(reverse, "BLUE", (val=2,&val));
H5Tenum_insert(reverse, "GREEN", (val=3,&val));
H5Tenum_insert(reverse, "RED", (val=4,&val));
/* Print data */
for (i=0; i<5; i++) {
H5Tenum_nameof(hdf_en_colors, data+i, sym, sizeof sym);
printf ("%d %s\n", data[i], sym);
}
puts("Converting...");
H5Tconvert(hdf_en_colors, reverse, 5, data, NULL);
/* Print data */
for (i=0; i<5; i++) {
H5Tenum_nameof(reverse, data+i, sym, sizeof sym);
printf ("%d %s\n", data[i], sym);
}</pre>
<p>
Output:
<pre>
0 RED
1 GREEN
2 BLUE
3 WHITE
4 BLACK
Converting...
4 RED
3 GREEN
2 BLUE
1 WHITE
0 BLACK</pre>
<h3>7.8. Equality</h2>
<p>The order that members are inserted into an enumeration type is
unimportant; the important part is the associations between the
symbol names and the values. Thus, two enumeration data types
will be considered equal if and only if both types have the same
symbol/value associations and both have equal underlying integer
data types. Type equality is tested with the
<code>H5Tequal()</code> function.
<h3>7.9. Interacting with C's <code>enum</code> Type</h2>
<p>Although HDF enumeration data types are similar to C
<code>enum</code> data types, there are some important
differences:
<p>
<center>
<table border width="80%">
<tr>
<th>Difference</th>
<th>Motivation/Implications</th>
</tr>
<tr>
<td valign=top>Symbols are unquoted in C but quoted in
HDF.</td>
<td valign=top>This allows the application to manipulate
symbol names in ways that are not possible with C.</td>
</tr>
<tr>
<td valign=top>The C compiler automatically replaces all
symbols with their integer values but HDF requires
explicit calls to do the same.</td>
<td valign=top>C resolves symbols at compile time while
HDF resolves symbols at run time.</td>
</tr>
<tr>
<td valign=top>The mapping from symbols to integers is
<em>N</em>:1 in C but 1:1 in HDF.</td>
<td valign=top>HDF can translate from value to name
uniquely and large <code>switch</code> statements are
not necessary to print values in human-readable
format.</td>
</tr>
<tr>
<td valign=top>A symbol must appear in only one C
<code>enum</code> type but may appear in multiple HDF
enumeration types.</td>
<td valign=top>The translation from symbol to value in HDF
requires the data type to be specified while in C the
data type is not necessary because it can be inferred
from the symbol.</td>
</tr>
<tr>
<td valign=top>The underlying integer value is always a
native integer in C but can be a foreign integer type in
HDF.</td>
<td valign=top>This allows HDF to describe data that might
reside on a foreign architecture, such as data stored in
a file.</td>
</tr>
<tr>
<td valign=top>The sign and size of the underlying integer
data type is chosen automatically by the C compiler but
must be fully specified with HDF.</td>
<td valign=top>Since HDF doesn't require finalization of a
data type, complete specification of the type must be
supplied before the type is used. Requiring that
information at the time of type creation was a design
decision to simplify the library.</td>
</tr>
</table>
</center>
<p>The examples below use the following C data types:
<p>
<table width="90%" bgcolor="white">
<tr>
<td>
<code><pre>
/* English color names */
typedef enum {
RED,
GREEN,
BLUE,
WHITE,
BLACK
} c_en_colors;
/* Spanish color names, reverse order */
typedef enum {
NEGRO
BLANCO,
AZUL,
VERDE,
ROJO,
} c_sp_colors;
/* No enum definition for French names */
</pre></code>
</td>
</tr>
</table>
<h4>Creating HDF Types from C Types</h3>
<p>An HDF enumeration data type can be created from a C
<code>enum</code> type simply by passing pointers to the C
<code>enum</code> values to <code>H5Tenum_insert()</code>. For
instance, to create HDF types for the <code>c_en_colors</code>
type shown above:
<p>
<table width="90%" bgcolor="white">
<tr>
<td>
<code><pre>
c_en_colors val;
hid_t hdf_en_colors = H5Tcreate(H5T_ENUM, sizeof(c_en_colors));
H5Tenum_insert(hdf_en_colors, "RED", (val=RED, &val));
H5Tenum_insert(hdf_en_colors, "GREEN", (val=GREEN,&val));
H5Tenum_insert(hdf_en_colors, "BLUE", (val=BLUE, &val));
H5Tenum_insert(hdf_en_colors, "WHITE", (val=WHITE,&val));
H5Tenum_insert(hdf_en_colors, "BLACK", (val=BLACK,&val));</pre></code>
</td>
</tr>
</table>
<h4>Name Changes between Applications</h3>
<p>Occassionally two applicatons wish to exchange data but they
use different names for the constants they exchange. For
instance, an English and a Spanish program may want to
communicate color names although they use different symbols in
the C <code>enum</code> definitions. The communication is still
possible although the applications must agree on common terms
for the colors. The following example shows the Spanish code to
read the values assuming that the applications have agreed that
the color information will be exchanged using Enlish color
names:
<p>
<table width="90%" bgcolor="white">
<tr>
<td>
<code><pre>
c_sp_colors val, data[1000];
hid_t hdf_sp_colors = H5Tcreate(H5T_ENUM, sizeof(c_sp_colors));
H5Tenum_insert(hdf_sp_colors, "RED", (val=ROJO, &val));
H5Tenum_insert(hdf_sp_colors, "GREEN", (val=VERDE, &val));
H5Tenum_insert(hdf_sp_colors, "BLUE", (val=AZUL, &val));
H5Tenum_insert(hdf_sp_colors, "WHITE", (val=BLANCO, &val));
H5Tenum_insert(hdf_sp_colors, "BLACK", (val=NEGRO, &val));
H5Dread(dataset, hdf_sp_colors, H5S_ALL, H5S_ALL, H5P_DEFAULT, data);</pre></code>
</td>
</tr>
</table>
<h4>Symbol Ordering across Applications</h3>
<p>Since symbol ordering is completely determined by the integer values
assigned to each symbol in the <code>enum</code> definition,
ordering of <code>enum</code> symbols cannot be preserved across
files like with HDF enumeration types. HDF can convert from one
application's integer values to the other's so a symbol in one
application's C <code>enum</code> gets mapped to the same symbol
in the other application's C <code>enum</code>, but the relative
order of the symbols is not preserved.
<p>For example, an application may be defined to use the
definition of <code>c_en_colors</code> defined above where
<code>WHITE</code> is less than <code>BLACK</code>, but some
other application might define the colors in some other
order. If each application defines an HDF enumeration type based
on that application's C <code>enum</code> type then HDF will
modify the integer values as data is communicated from one
application to the other so that a <code>RED</code> value
in the first application is also a <code>RED</code> value in the
other application.
<p>A case of this reordering of symbol names was also shown in the
previous code snippet (as well as a change of language), where
HDF changed the integer values so 0 (<code>RED</code>) in the
input file became 4 (<code>ROJO</code>) in the <code>data</code>
array. In the input file, <code>WHITE</code> was less than
<code>BLACK</code>; in the application the opposite is true.
<p>In fact, the ability to change the order of symbols is often
convenient when the enumeration type is used only to group
related symbols that don't have any well defined order
relationship.
<h4>Internationalization</h3>
<p>The HDF enumeration type conversion features can also be used
to provide internationalization of debugging output. A program
written with the <code>c_en_colors</code> data type could define
a separate HDF data type for languages such as English, Spanish,
and French and cast the enumerated value to one of these HDF
types to print the result.
<p>
<table width="90%" bgcolor="white">
<tr>
<td>
<code><pre>
c_en_colors val, *data=...;
hid_t hdf_sp_colors = H5Tcreate(H5T_ENUM, sizeof val);
H5Tenum_insert(hdf_sp_colors, "ROJO", (val=RED, &val));
H5Tenum_insert(hdf_sp_colors, "VERDE", (val=GREEN, &val));
H5Tenum_insert(hdf_sp_colors, "AZUL", (val=BLUE, &val));
H5Tenum_insert(hdf_sp_colors, "BLANCO", (val=WHITE, &val));
H5Tenum_insert(hdf_sp_colors, "NEGRO", (val=BLACK, &val));
hid_t hdf_fr_colors = H5Tcreate(H5T_ENUM, sizeof val);
H5Tenum_insert(hdf_fr_colors, "OUGE", (val=RED, &val));
H5Tenum_insert(hdf_fr_colors, "VERT", (val=GREEN, &val));
H5Tenum_insert(hdf_fr_colors, "BLEU", (val=BLUE, &val));
H5Tenum_insert(hdf_fr_colors, "BLANC", (val=WHITE, &val));
H5Tenum_insert(hdf_fr_colors, "NOIR", (val=BLACK, &val));
void
nameof(lang_t language, c_en_colors val, char *name, size_t size)
{
switch (language) {
case ENGLISH:
H5Tenum_nameof(hdf_en_colors, &val, name, size);
break;
case SPANISH:
H5Tenum_nameof(hdf_sp_colors, &val, name, size);
break;
case FRENCH:
H5Tenum_nameof(hdf_fr_colors, &val, name, size);
break;
}
}</pre></code>
</td>
</tr>
</table>
<h3>7.10. Goals That Have Been Met</h2>
<p>The main goal of enumeration types is to provide communication
of enumerated data using symbolic equivalence. That is, a
symbol written to a dataset by one application should be read as
the same symbol by some other application.
<p>
<table width="90%">
<tr>
<td valign=top><b>Architecture Independence</b></td>
<td valign=top>Two applications shall be able to exchange
enumerated data even when the underlying integer values
have different storage formats. HDF accomplishes this for
enumeration types by building them upon integer types.</td>
</tr>
<tr>
<td valign=top><b>Preservation of Order Relationship</b></td>
<td valign=top>The relative order of symbols shall be
preserved between two applications that use equivalent
enumeration data types. Unlike numeric values that have
an implicit ordering, enumerated data has an explicit
order defined by the enumeration data type and HDF
records this order in the file.</td>
</tr>
<tr>
<td valign=top><b>Order Independence</b></td>
<td valign=top>An application shall be able to change the
relative ordering of the symbols in an enumeration data
type. This is accomplished by defining a new type with
different integer values and converting data from one type
to the other.</td>
</tr>
<tr>
<td valign=top><b>Subsets</b></td>
<td valign=top>An application shall be able to read
enumerated data from an archived dataset even after the
application has defined additional members for the
enumeration type. An application shall be able to write
to a dataset when the dataset contains a superset of the
members defined by the application. Similar rules apply
for in-core conversions between enumerated data
types.</td>
</tr>
<tr>
<td valign=top><b>Targetable</b></td>
<td valign=top>An application shall be able to target a
particular architecture or application when storing
enumerated data. This is accomplished by allowing
non-native underlying integer types and converting the
native data to non-native data.</td>
</tr>
<tr>
<td valign=top><b>Efficient Data Transfer</b></td>
<td valign=top>An application that defines a file dataset
that corresponds to some native C enumerated data array
shall be able to read and write to that dataset directly
using only Posix read and write functions. HDF already
optimizes this case for integers, so the same optimization
will apply to enumerated data.
</tr>
<tr>
<td valign=top><b>Efficient Storage</b></td>
<td valign=top>Enumerated data shall be stored in a manner
which is space efficient. HDF stores the enumerated data
as integers and allows the application to chose the size
and format of those integers.</td>
</tr>
</table>
<p align=right><font size=-1><i>
(Return to <a href="Datatypes.html#Datatypes_Enum">Data Types Interface (H5T)</a>.)
</font></i>
<hr>
<center>
<table border=0 width=98%>
<tr><td valign=top align=left>
<a href="H5.intro.html">Introduction to HDF5</a> <br>
<a href="RM_H5Front.html">HDF5 Reference Manual</a> <br>
<a href="index.html">Other HDF5 documents and links</a> <br>
<!--
<a href="Glossary.html">Glossary</a><br>
-->
</td>
<td valign=top align=right>
And in this document, the
<a href="H5.user.html">HDF5 User's Guide</a>:
<a href="Files.html">Files</a>
<br>
<a href="Datasets.html">Datasets</a>
Data Types
<a href="Dataspaces.html">Dataspaces</a>
<a href="Groups.html">Groups</a>
<a href="References.html">References</a>
<br>
<a href="Attributes.html">Attributes</a>
<a href="Properties.html">Property Lists</a>
<a href="Errors.html">Error Handling</a>
<a href="Filters.html">Filters</a>
<a href="Caching.html">Caching</a>
<br>
<a href="Chunking.html">Chunking</a>
<a href="Debugging.html">Debugging</a>
<a href="Environment.html">Environment</a>
<a href="ddl.html">DDL</a>
<a href="Ragged.html">Ragged Arrays</a>
<!--
<hr>
And in this document, the
<a href="H5.user.html">HDF5 User's Guide</a>:
<a href="Attributes.html">H5A</a>
<a href="Datasets.html">H5D</a>
<a href="Errors.html">H5E</a>
<a href="Files.html">H5F</a>
<a href="Groups.html">H5G</a>
<a href="Properties.html">H5P</a>
<a href="References.html">H5R & H5I</a>
<a href="Ragged.html">H5RA</a>
<a href="Dataspaces.html">H5S</a>
<a href="Datatypes.html">H5T</a>
<a href="Filters.html">H5Z</a>
<a href="Caching.html">Caching</a>
<a href="Chunking.html">Chunking</a>
<a href="Debugging.html">Debugging</a>
<a href="Environment.html">Environment</a>
<a href="ddl.html">DDL</a>
-->
</td></tr>
</table>
</center>
<hr>
<address>
THG Help Desk: <img src="../Graphics/help.png" align=top height=16>
</address>
<!-- Created: Thu Dec 4 14:57:32 EST 1997 -->
<!-- hhmts start -->
Last modified: 30 April 1999
Footer modified: 3 July 2002
<!-- hhmts end -->
<br>
This file is longer used; the material has been integrated into Datatypes.html.
</body>
</html>
|