summaryrefslogtreecommitdiffstats
path: root/doc/html/DatatypesEnum.html
blob: 2926e7c5551a269f22be1e0b07a0a295a6adf648 (plain)
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
<!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>&nbsp;<br>
   <a href="RM_H5Front.html">HDF5 Reference Manual</a>&nbsp;<br>
   <a href="index.html">Other HDF5 documents and links</a>&nbsp;<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>:&nbsp;&nbsp;&nbsp;&nbsp;
      <a href="Files.html">Files</a>&nbsp;&nbsp;
      <br>
      <a href="Datasets.html">Datasets</a>&nbsp;&nbsp;
      <a href="Datatypes.html">Data Types</a>&nbsp;&nbsp;
      <a href="Dataspaces.html">Dataspaces</a>&nbsp;&nbsp;
      <a href="Groups.html">Groups</a>&nbsp;&nbsp;
      <a href="References.html">References</a>&nbsp;&nbsp;
      <br>
      <a href="Attributes.html">Attributes</a>&nbsp;&nbsp;
      <a href="Properties.html">Property Lists</a>&nbsp;&nbsp;
      <a href="Errors.html">Error Handling</a>&nbsp;&nbsp;
      <a href="Filters.html">Filters</a>&nbsp;&nbsp;
      <a href="Caching.html">Caching</a>&nbsp;&nbsp;
      <br>
      <a href="Chunking.html">Chunking</a>&nbsp;&nbsp;
      <a href="Debugging.html">Debugging</a>&nbsp;&nbsp;
      <a href="Environment.html">Environment</a>&nbsp;&nbsp;
      <a href="ddl.html">DDL</a>&nbsp;&nbsp;
      <a href="Ragged.html">Ragged Arrays</a>&nbsp;&nbsp;
<!--
<hr>
And in this document, the 
<a href="H5.user.html">HDF5 User's Guide</a>:&nbsp;&nbsp;&nbsp;&nbsp;
      <a href="Attributes.html">H5A</a>&nbsp;&nbsp;
      <a href="Datasets.html">H5D</a>&nbsp;&nbsp;
      <a href="Errors.html">H5E</a>&nbsp;&nbsp;
      <a href="Files.html">H5F</a>&nbsp;&nbsp;
      <a href="Groups.html">H5G</a>&nbsp;&nbsp;
      <a href="Properties.html">H5P</a>&nbsp;&nbsp;
      <a href="References.html">H5R & H5I</a>&nbsp;&nbsp;
      <a href="Ragged.html">H5RA</a>&nbsp;&nbsp;
      <a href="Dataspaces.html">H5S</a>&nbsp;&nbsp;
      <a href="Datatypes.html">H5T</a>&nbsp;&nbsp;
      <a href="Filters.html">H5Z</a>&nbsp;&nbsp;
      <a href="Caching.html">Caching</a>&nbsp;&nbsp;
      <a href="Chunking.html">Chunking</a>&nbsp;&nbsp;
      <a href="Debugging.html">Debugging</a>&nbsp;&nbsp;
      <a href="Environment.html">Environment</a>&nbsp;&nbsp;
      <a href="ddl.html">DDL</a>&nbsp;&nbsp;
-->
</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,&amp;val));
H5Tenum_insert(hdf_en_colors, "GREEN", (val=1,&amp;val));
H5Tenum_insert(hdf_en_colors, "BLUE",  (val=2,&amp;val));
H5Tenum_insert(hdf_en_colors, "WHITE", (val=3,&amp;val));
H5Tenum_insert(hdf_en_colors, "BLACK", (val=4,&amp;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,&amp;val));
H5Tenum_insert(hdf_fr_colors, "vert",  (val=1,&amp;val));
H5Tenum_insert(hdf_fr_colors, "bleu",  (val=2,&amp;val));
H5Tenum_insert(hdf_fr_colors, "blanc", (val=3,&amp;val));
H5Tenum_insert(hdf_fr_colors, "noir",  (val=4,&amp;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>, int
	  <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>, int
	  <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 i, n = H5Tget_nmembers(hdf_en_colors);
for (i=0; i&lt;n; i++) {
    char *symbol = H5Tget_member_name(hdf_en_colors, i);
    short val;
    H5Tget_member_value(hdf_en_colors, i, &amp;val);
    printf("#%d %20s = %d\n", i, 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))&lt;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,&amp;val));
H5Tenum_insert(bits, "GREEN", (val=0x0002,&amp;val));
H5Tenum_insert(bits, "BLUE",  (val=0x0004,&amp;val));
H5Tenum_insert(bits, "WHITE", (val=0x0008,&amp;val));
H5Tenum_insert(bits, "BLACK", (val=0x0010,&amp;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&lt;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", &amp;val1);
H5Tenum_valueof(hdf_en_colors, "BLACK", &amp;val2);
if (val1 &lt; 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*));
int i;

/* Get foreign type information */
for (i=0; i&lt;n; i++) {
    name[i] = H5Tget_member_name(foreign, i);
    H5Tget_member_value(foreign, i,
                        (char*)val+i*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&lt;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,&amp;val));
H5Tenum_insert(reverse, "WHITE", (val=1,&amp;val));
H5Tenum_insert(reverse, "BLUE",  (val=2,&amp;val));
H5Tenum_insert(reverse, "GREEN", (val=3,&amp;val));
H5Tenum_insert(reverse, "RED",   (val=4,&amp;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,  &amp;val));
H5Tenum_insert(hdf_en_colors, "GREEN", (val=GREEN,&amp;val));
H5Tenum_insert(hdf_en_colors, "BLUE",  (val=BLUE, &amp;val));
H5Tenum_insert(hdf_en_colors, "WHITE", (val=WHITE,&amp;val));
H5Tenum_insert(hdf_en_colors, "BLACK", (val=BLACK,&amp;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,   &amp;val));
H5Tenum_insert(hdf_sp_colors, "GREEN", (val=VERDE,  &amp;val));
H5Tenum_insert(hdf_sp_colors, "BLUE",  (val=AZUL,   &amp;val));
H5Tenum_insert(hdf_sp_colors, "WHITE", (val=BLANCO, &amp;val));
H5Tenum_insert(hdf_sp_colors, "BLACK", (val=NEGRO,  &amp;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,   &amp;val));
H5Tenum_insert(hdf_sp_colors, "VERDE",  (val=GREEN, &amp;val));
H5Tenum_insert(hdf_sp_colors, "AZUL",   (val=BLUE,  &amp;val));
H5Tenum_insert(hdf_sp_colors, "BLANCO", (val=WHITE, &amp;val));
H5Tenum_insert(hdf_sp_colors, "NEGRO",  (val=BLACK, &amp;val));

hid_t hdf_fr_colors = H5Tcreate(H5T_ENUM, sizeof val);
H5Tenum_insert(hdf_fr_colors, "OUGE",  (val=RED,   &amp;val));
H5Tenum_insert(hdf_fr_colors, "VERT",  (val=GREEN, &amp;val));
H5Tenum_insert(hdf_fr_colors, "BLEU",  (val=BLUE,  &amp;val));
H5Tenum_insert(hdf_fr_colors, "BLANC", (val=WHITE, &amp;val));
H5Tenum_insert(hdf_fr_colors, "NOIR",  (val=BLACK, &amp;val));

void
nameof(lang_t language, c_en_colors val, char *name, size_t size)
{
    switch (language) {
    case ENGLISH:
        H5Tenum_nameof(hdf_en_colors, &amp;val, name, size);
        break;
    case SPANISH:
        H5Tenum_nameof(hdf_sp_colors, &amp;val, name, size);
        break;
    case FRENCH:
        H5Tenum_nameof(hdf_fr_colors, &amp;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>&nbsp;<br>
   <a href="RM_H5Front.html">HDF5 Reference Manual</a>&nbsp;<br>
   <a href="index.html">Other HDF5 documents and links</a>&nbsp;<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>:&nbsp;&nbsp;&nbsp;&nbsp;
      <a href="Files.html">Files</a>&nbsp;&nbsp;
      <br>
      <a href="Datasets.html">Datasets</a>&nbsp;&nbsp;
      Data Types&nbsp;&nbsp;
      <a href="Dataspaces.html">Dataspaces</a>&nbsp;&nbsp;
      <a href="Groups.html">Groups</a>&nbsp;&nbsp;
      <a href="References.html">References</a>&nbsp;&nbsp;
      <br>
      <a href="Attributes.html">Attributes</a>&nbsp;&nbsp;
      <a href="Properties.html">Property Lists</a>&nbsp;&nbsp;
      <a href="Errors.html">Error Handling</a>&nbsp;&nbsp;
      <a href="Filters.html">Filters</a>&nbsp;&nbsp;
      <a href="Caching.html">Caching</a>&nbsp;&nbsp;
      <br>
      <a href="Chunking.html">Chunking</a>&nbsp;&nbsp;
      <a href="Debugging.html">Debugging</a>&nbsp;&nbsp;
      <a href="Environment.html">Environment</a>&nbsp;&nbsp;
      <a href="ddl.html">DDL</a>&nbsp;&nbsp;
      <a href="Ragged.html">Ragged Arrays</a>&nbsp;&nbsp;
<!--
<hr>
And in this document, the 
<a href="H5.user.html">HDF5 User's Guide</a>:&nbsp;&nbsp;&nbsp;&nbsp;
      <a href="Attributes.html">H5A</a>&nbsp;&nbsp;
      <a href="Datasets.html">H5D</a>&nbsp;&nbsp;
      <a href="Errors.html">H5E</a>&nbsp;&nbsp;
      <a href="Files.html">H5F</a>&nbsp;&nbsp;
      <a href="Groups.html">H5G</a>&nbsp;&nbsp;
      <a href="Properties.html">H5P</a>&nbsp;&nbsp;
      <a href="References.html">H5R & H5I</a>&nbsp;&nbsp;
      <a href="Ragged.html">H5RA</a>&nbsp;&nbsp;
      <a href="Dataspaces.html">H5S</a>&nbsp;&nbsp;
      <a href="Datatypes.html">H5T</a>&nbsp;&nbsp;
      <a href="Filters.html">H5Z</a>&nbsp;&nbsp;
      <a href="Caching.html">Caching</a>&nbsp;&nbsp;
      <a href="Chunking.html">Chunking</a>&nbsp;&nbsp;
      <a href="Debugging.html">Debugging</a>&nbsp;&nbsp;
      <a href="Environment.html">Environment</a>&nbsp;&nbsp;
      <a href="ddl.html">DDL</a>&nbsp;&nbsp;
-->
</td></tr>
</table>
</center>


<hr>
<address>
<a href="mailto:hdfhelp@ncsa.uiuc.edu">HDF Help Desk</a>
</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>