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
|
/****************************************************************************
* NCSA HDF *
* Software Development Group *
* National Center for Supercomputing Applications *
* University of Illinois at Urbana-Champaign *
* 605 E. Springfield, Champaign IL 61820 *
* *
* For conditions of distribution and use, see the accompanying *
* hdf/COPYING file. *
* *
****************************************************************************/
#ifdef RCSID
static char RcsId[] = "@(#)$Revision$";
#endif
/* $Id$ */
/*LINTLIBRARY */
/*+
FILE
H5T.c
HDF5 Data-type routines
EXPORTED ROUTINES
H5Tget_num_fields -- Get the number of fields in a compound datatype
H5Tis_field_atomic -- Check if a field is atomic
H5Tis_atomic -- Check if a datatype is atomic
H5Tset_type -- Set the base type of a user-defined datatype
H5Tadd_field -- Add a field to a compound datatype
H5Tsize -- Determine the size of a datatype
LIBRARY-SCOPED ROUTINES
H5T_create -- (Meta-Object) Create a datatype
H5T_release -- (Meta-Object) Release access to a datatype
LOCAL ROUTINES
H5T_init_interface -- initialize the interface
+ */
#include <H5private.h> /* Generic Functions */
#include <H5Aprivate.h> /* Atom functions */
#include <H5Eprivate.h> /* Error handling */
#include <H5Mprivate.h> /* Meta data */
#include <H5Pprivate.h> /* Data space */
#include <H5Tprivate.h> /* Data-type functions */
#define PABLO_MASK H5T_mask
/*--------------------- Locally scoped variables -----------------------------*/
/* Whether we've installed the library termination function yet for this interface */
static intn interface_initialize_g = FALSE;
/*------------------_-- Local function prototypes ----------------------------*/
static herr_t H5T_init_interface(void);
/*--------------------------------------------------------------------------
NAME
H5T_init_interface -- Initialize interface-specific information
USAGE
herr_t H5T_init_interface()
RETURNS
SUCCEED/FAIL
DESCRIPTION
Initializes any interface-specific data or routines.
--------------------------------------------------------------------------*/
static herr_t H5T_init_interface(void)
{
herr_t ret_value = SUCCEED;
FUNC_ENTER (H5T_init_interface, NULL, FAIL);
/* Initialize the atom group for the file IDs */
ret_value=H5Ainit_group(H5_DATATYPE,H5A_DATATYPEID_HASHSIZE,H5T_RESERVED_ATOMS);
FUNC_LEAVE(ret_value);
} /* H5T_init_interface */
/*--------------------------------------------------------------------------
NAME
H5T_create
PURPOSE
Create a new HDF5 data-type object
USAGE
hatom_t H5T_create(owner_id, type, name)
hatom_t owner_id; IN: Group/file which owns this object
hobjtype_t type; IN: Type of object to create
const char *name; IN: Name of the object
RETURNS
Returns ID (atom) on success, FAIL on failure
DESCRIPTION
This function actually creates the data-type object.
--------------------------------------------------------------------------*/
hatom_t H5T_create(hatom_t owner_id, hobjtype_t type, const char *name)
{
h5_datatype_t *new_dt; /* new data-type object to create */
hatom_t ret_value = SUCCEED;
FUNC_ENTER(H5T_create, H5T_init_interface, FAIL);
/* Clear errors and check args and all the boring stuff. */
H5ECLEAR;
/* Allocate space for the new data-type */
if((new_dt=HDmalloc(sizeof(h5_datatype_t)))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
/* Initialize the datatype */
new_dt->dt.base=0; /* No Default datatype */
new_dt->name=HDstrdup(name); /* Make a copy of the datatype's name */
new_dt->ci=NULL; /* Set the complex information to NULL */
/* Register the new datatype and get an ID for it */
if((ret_value=H5Aregister_atom(H5_DATATYPE, (const VOIDP)new_dt))==FAIL)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL);
done:
if(ret_value == FAIL)
{ /* Error condition cleanup */
} /* end if */
/* Normal function cleanup */
FUNC_LEAVE(ret_value);
} /* end H5T_create() */
/*--------------------------------------------------------------------------
NAME
H5Tget_num_fields
PURPOSE
Return the number of fields in a compound datatype
USAGE
uint32 H5Tget_num_fields(tid)
hatom_t tid; IN: Datatype object to query
RETURNS
The number of fields in a compound datatype on success, UFAIL on failure
DESCRIPTION
This function checks the number of fields in a compound user-defined
datatype. UFAIL is returned on an error or if an atomic datatype is
queried, otherwise the number of fields is returned.
--------------------------------------------------------------------------*/
uint32 H5Tget_num_fields(hatom_t tid)
{
h5_datatype_t *dt; /* new data-type object to create */
uint32 ret_value = UFAIL;
FUNC_ENTER(H5Tget_num_fields, H5T_init_interface, UFAIL);
/* Clear errors and check args and all the boring stuff. */
H5ECLEAR;
/* Go get the object */
if((dt=H5Aatom_object(tid))==NULL)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
/* Check the base type of the datatype */
if(H5T_COMPOUND!=dt->dt.base)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL);
/* Check if the compound information has been initialized */
if(NULL==dt->ci)
HGOTO_ERROR(H5E_INTERNAL, H5E_UNINITIALIZED, FAIL);
/* Grab the number of fields */
ret_value=dt->ci->n;
done:
if(ret_value == UFAIL)
{ /* Error condition cleanup */
} /* end if */
/* Normal function cleanup */
FUNC_LEAVE(ret_value);
} /* end H5Tget_num_fields() */
/*--------------------------------------------------------------------------
NAME
H5Tis_field_atomic
PURPOSE
Check if a field in a compound datatype is atomic
USAGE
hbool_t H5Tis_field_atomic(tid, fidx)
hatom_t tid; IN: Datatype object to query
uintn fidx; IN: Index of the field to query
RETURNS
BFAIL/BTRUE/BFALSE
DESCRIPTION
This function checks the basic type of field in a user-defined datatype.
BTRUE is returned if the datatype is atomic (i.e. not compound), BFALSE is
returned if the datatype is compound, BFAIL on error.
--------------------------------------------------------------------------*/
hbool_t H5Tis_field_atomic(hatom_t tid, uintn fidx)
{
h5_datatype_t *dt; /* new data-type object to create */
hbool_t ret_value = BTRUE;
FUNC_ENTER(H5Tis_field_atomic, H5T_init_interface, BFAIL);
/* Clear errors and check args and all the boring stuff. */
H5ECLEAR;
/* Go get the object */
if((dt=H5Aatom_object(tid))==NULL)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
/* Check the base type of the datatype */
if(H5T_COMPOUND!=dt->dt.base)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL);
/* Check if the compound information has been initialized */
if(NULL==dt->ci)
HGOTO_ERROR(H5E_INTERNAL, H5E_UNINITIALIZED, FAIL);
/* Check if the field is valid*/
if(fidx>=dt->ci->n)
HGOTO_ERROR(H5E_INTERNAL, H5E_BADRANGE, FAIL);
/* Check the base type of the field */
if(H5T_COMPOUND==dt->ci->flist[fidx].dt.base || H5P_SCALAR!=dt->ci->flist[fidx].dim_id)
ret_value=BFALSE;
done:
if(ret_value == BFAIL)
{ /* Error condition cleanup */
} /* end if */
/* Normal function cleanup */
FUNC_LEAVE(ret_value);
} /* end H5Tis_field_atomic() */
/*--------------------------------------------------------------------------
NAME
H5Tis_atomic
PURPOSE
Check if a datatype is atomic
USAGE
hbool_t H5Tis_atomic(tid)
hatom_t tid; IN: Datatype object to query
RETURNS
BFAIL/BTRUE/BFALSE
DESCRIPTION
This function checks the basic type of a user-defined datatype. BTRUE
is returned if the datatype is atomic (i.e. not compound), BFALSE is
returned if the datatype is compound, BFAIL on error.
--------------------------------------------------------------------------*/
hbool_t H5Tis_atomic(hatom_t tid)
{
h5_datatype_t *dt; /* new data-type object to create */
hbool_t ret_value = BTRUE;
FUNC_ENTER(H5Tis_atomic, H5T_init_interface, BFAIL);
/* Clear errors and check args and all the boring stuff. */
H5ECLEAR;
/* Go get the object */
if((dt=H5Aatom_object(tid))==NULL)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
/* Check the base type of the datatype */
if(H5T_COMPOUND==dt->dt.base)
ret_value=BFALSE;
done:
if(ret_value == BFAIL)
{ /* Error condition cleanup */
} /* end if */
/* Normal function cleanup */
FUNC_LEAVE(ret_value);
} /* end H5Tis_atomic() */
/*--------------------------------------------------------------------------
NAME
H5Tset_type
PURPOSE
Set the base type of a user-defined datatype
USAGE
herr_t H5Tset_type(tid, base, len, arch)
hatom_t tid; IN: Datatype object to modify
hatom_t base; IN: Base type to set the datatype to
uint8 len; IN: Length of the object in bytes
uint8 arch; IN: Architecture format to store type with
RETURNS
SUCCEED/FAIL
DESCRIPTION
This function sets the basic type of a user-defined datatype. Each
datatype is either an atomic type (i.e. has no further divisions of the
type) or is a compound type (like a C structure). If the datatype is set
to a compound type, the 'len' argument is not used.
--------------------------------------------------------------------------*/
herr_t H5Tset_type(hatom_t tid,hatom_t base,uint8 len,uint8 arch)
{
h5_datatype_t *dt; /* new data-type object to create */
herr_t ret_value = SUCCEED;
FUNC_ENTER(H5Tset_type, H5T_init_interface, FAIL);
/* Clear errors and check args and all the boring stuff. */
H5ECLEAR;
if(base<H5T_CHAR || base>H5T_COMPOUND)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL);
/* Go get the object */
if((dt=H5Aatom_object(tid))==NULL)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
if(dt->dt.base!=0)
HGOTO_ERROR(H5E_FUNC, H5E_ALREADYINIT, FAIL);
/* Set the basic datatype information */
dt->dt.base=base;
dt->dt.len=len;
dt->dt.arch=arch;
done:
if(ret_value == FAIL)
{ /* Error condition cleanup */
} /* end if */
/* Normal function cleanup */
FUNC_LEAVE(ret_value);
} /* end H5Tset_type() */
/*--------------------------------------------------------------------------
NAME
H5Tadd_field
PURPOSE
Add a field to a compound datatype
USAGE
herr_t H5Tadd_field(tid, name, base, len, arch, space)
hatom_t tid; IN: Datatype object to query
const char *fidx; IN: Field name
hatom_t base; IN: Field's base type, either an atom ID for
an existing compound type, or an atomic
base type
uint8 len; IN: Length of an atomic base type
uint8 arch; IN: Architecture format of an atomic base type
hatom_t space; IN: The dimensionality of the field to add
RETURNS
SUCCEED/FAIL
DESCRIPTION
This function adds a field to a user-defined compound datatype. The
field can either be a base/len/arch triplet or an existing compound type
(passed in the base argument). The space parameter is either H5P_SCALAR
(to indicate a scalar field) or the atom of a datatype for more complex
dimensionality fields.
--------------------------------------------------------------------------*/
herr_t H5Tadd_field(hatom_t tid, const char *name, hatom_t base, uint8 len, uint8 arch, hatom_t space)
{
h5_field_info_t *new_field; /* pointer to new field to add */
h5_datatype_t *dt; /* data-type object to manipulate */
herr_t ret_value = SUCCEED;
FUNC_ENTER(H5Tadd_field, H5T_init_interface, FAIL);
/* Clear errors and check args and all the boring stuff. */
H5ECLEAR;
/* Go get the object */
if((dt=H5Aatom_object(tid))==NULL)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
/* Check the base type of the datatype */
if(H5T_COMPOUND!=dt->dt.base)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL);
/* Check if the compound information has been initialized */
if(NULL==dt->ci)
{
if(NULL==(dt->ci=HDmalloc(sizeof(h5_compound_info_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
dt->ci->n=0; /* Set the number of fields to 0 */
dt->ci->mem_size=0; /* Set the size of the structure */
dt->ci->disk_size=0; /* Set the size of the structure */
dt->ci->flist=NULL; /* No field information yet */
} /* end if */
if(NULL==(new_field=HDrealloc(dt->ci->flist,(dt->ci->n+1)*sizeof(h5_field_info_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
dt->ci->n++; /* increment the number of fields */
dt->ci->flist=new_field; /* save the pointer to the increased array of fields */
new_field=&dt->ci->flist[dt->ci->n-1]; /* get a "convenience" pointer to the new field */
new_field->name=HDstrdup(name); /* copy the name */
new_field->name_off=0; /* name isn't stored yet */
new_field->struct_off=dt->ci->disk_size; /* Set the offset of the field on disk */
new_field->dim_id=H5Mcopy(space); /* Make a copy of the dimension space for the field */
if((H5Ais_reserved(base)==BTRUE) && base!=H5T_COMPOUND) /* Check if this is a "simple" datatype */
{
new_field->dt.base=base; /* Make a copy of the datatype for the field */
new_field->dt.len=len;
new_field->dt.arch=arch;
} /* end if */
else
{
new_field->dt.base=H5Mcopy(base); /* Make a copy of the datatype for the field */
new_field->dt.len=H5Tsize(base,len,arch,BTRUE);
new_field->dt.arch=arch;
} /* end else */
done:
if(ret_value == FAIL)
{ /* Error condition cleanup */
} /* end if */
/* Normal function cleanup */
FUNC_LEAVE(ret_value);
} /* end H5Tadd_field() */
/*--------------------------------------------------------------------------
NAME
H5Tsize
PURPOSE
Determine the size of a datatype
USAGE
uintn H5Tsize(tid, mem_flag)
hatom_t tid; IN: Datatype object to query
hbool_t mem_flag; IN: Whether the memory or disk size is desired
RETURNS
The size of the datatype on success or UFAIL on failure.
DESCRIPTION
Ths function returns the size of the datatype in bytes as it is stored
on disk or in memory, depending on the mem_flag. Setting the mem_flag to
BTRUE returns the size in memory, BFALSE returns the size on disk.
--------------------------------------------------------------------------*/
uintn H5Tsize(hatom_t tid, uint8 len, uint8 arch, hbool_t mem_flag)
{
uintn ret_value = UFAIL;
FUNC_ENTER(H5Tsize, H5T_init_interface, UFAIL);
/* Clear errors and check args and all the boring stuff. */
H5ECLEAR;
if((H5Ais_reserved(tid)==BTRUE) && tid!=H5T_COMPOUND) /* Check if this is a "simple" datatype */
{
switch(tid)
{
case H5T_CHAR:
case H5T_INT:
case H5T_FLOAT: /* All three of thes types use the length as the number of bytes */
ret_value=len;
break;
case H5T_DATE:
ret_value=8; /* Number of characters for ISO 8601 format */
break;
case H5T_TIME:
ret_value=6; /* Number of characters for ISO 8601 format */
break;
case H5T_SPTR:
HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, UFAIL);
break;
case H5T_PPTR:
HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, UFAIL);
break;
default:
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, UFAIL);
} /* end switch */
} /* end if */
else
{
if(tid==H5T_COMPOUND)
{
intn i; /* local counting variable */
h5_datatype_t *dt; /* datatype pointer */
/* Go get the object */
if((dt=H5Aatom_object(tid))==NULL)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
/* Check the base type of the datatype */
if(H5T_COMPOUND!=dt->dt.base)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL);
/* Check if the compound information has been initialized */
if(NULL==dt->ci)
HGOTO_ERROR(H5E_INTERNAL, H5E_UNINITIALIZED, FAIL);
/* Grab the number of fields */
for(i=0; i<=dt->ci->n; i++)
ret_value+=H5Tsize(dt->ci->flist[i].dt.base, dt->ci->flist[i].dt.len,
dt->ci->flist[i].dt.arch,mem_flag)*H5Pnelem(dt->ci->flist[i].dim_id);
} /* end if */
} /* end else */
done:
if(ret_value == UFAIL)
{ /* Error condition cleanup */
} /* end if */
/* Normal function cleanup */
FUNC_LEAVE(ret_value);
} /* end H5Tsize() */
/*--------------------------------------------------------------------------
NAME
H5Tget_fields
PURPOSE
Determine the size of a datatype
USAGE
herr_t H5Tget_fields(tid, field_list)
hatom_t tid; IN: Datatype object to query
hoid_t *field_list; IN: Array to store list of fields
RETURNS
SUCCEED/FAIL
DESCRIPTION
Ths function returns a list of OIDs for the fields in a compound
datatype. Atomic fields are returned in the list of OIDs, but have special
OID values which cannot be further dereferenced.
--------------------------------------------------------------------------*/
herr_t H5Tget_fields(hatom_t tid, hatom_t *field_list)
{
herr_t ret_value = FAIL;
FUNC_ENTER(H5Tget_fields, H5T_init_interface, FAIL);
/* Clear errors and check args and all the boring stuff. */
H5ECLEAR;
if(H5Aatom_group(tid)!=H5_DATATYPE)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
if(field_list==NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL);
done:
if(ret_value == UFAIL)
{ /* Error condition cleanup */
} /* end if */
/* Normal function cleanup */
FUNC_LEAVE(ret_value);
} /* end H5Tget_fields() */
/*--------------------------------------------------------------------------
NAME
H5T_release
PURPOSE
Release access to an HDF5 datatype object.
USAGE
herr_t H5T_release(oid)
hatom_t oid; IN: Object to release access to
RETURNS
SUCCEED/FAIL
DESCRIPTION
This function releases a datatype from active use by a user.
--------------------------------------------------------------------------*/
herr_t H5T_release(hatom_t oid)
{
h5_datatype_t *dt; /* new data-type object to create */
herr_t ret_value = SUCCEED;
FUNC_ENTER(H5T_release, H5T_init_interface, FAIL);
/* Clear errors and check args and all the boring stuff. */
H5ECLEAR;
/* Chuck the object! :-) */
if((dt=H5Aremove_atom(oid))==NULL)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL);
if(dt->name!=NULL)
HDfree(dt->name);
if(dt->ci!=NULL)
{
} /* end if */
HDfree(dt);
done:
if(ret_value == FAIL)
{ /* Error condition cleanup */
} /* end if */
/* Normal function cleanup */
FUNC_LEAVE(ret_value);
} /* end H5T_release() */
|