#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <H5Fpublic.h>
#include <H5Ppublic.h>
#include <H5Gpublic.h>
#include <H5Spublic.h>
#include <H5Tpublic.h>
#include <H5Apublic.h>
#include "mhdf.h"
#include "status.h"
#include "names-and-paths.h"
#include "util.h"
#include "file-handle.h"
Go to the source code of this file.
Functions | |
static int | make_hdf_group (const char *path, hid_t file, size_t size, mhdf_Status *status) |
mhdf_FileHandle | mhdf_createFile (const char *filename, int overwrite, const char **elem_type_list, size_t elem_list_len, hid_t id_type, mhdf_Status *status) |
Create a new file. More... | |
mhdf_FileHandle | mhdf_openFile (const char *filename, int writeable, unsigned long *max_id_out, hid_t id_type, mhdf_Status *status) |
Open an existing file. More... | |
int | mhdf_countOpenHandles (mhdf_FileHandle file_handle) |
Get number of open HDF5 objects from file. More... | |
static herr_t | get_max_id (hid_t group_id, const char *subgroup, const char *datatable, unsigned long *data) |
static herr_t | max_id_iter (hid_t group_id, const char *name, void *data) |
static int | scan_for_max_id (FileHandle *file_ptr, mhdf_Status *status) |
mhdf_FileHandle | mhdf_openFileWithOpt (const char *filename, int writable, unsigned long *max_id_out, hid_t id_type, hid_t access_prop, mhdf_Status *status) |
Open an existing file with options. More... | |
void | mhdf_getElemName (mhdf_FileHandle file_handle, unsigned int type_index, char *buffer, size_t buf_size, mhdf_Status *status) |
Given an element type Id, get the name. Fails if buffer is not of sufficient size. More... | |
int | mhdf_checkOpenHandles (mhdf_FileHandle handle, mhdf_Status *status) |
void | mhdf_closeFile (mhdf_FileHandle handle, mhdf_Status *status) |
Close the file. More... | |
void | mhdf_closeData (mhdf_FileHandle file, hid_t handle, mhdf_Status *status) |
Common close function for all data handle types. More... | |
void | mhdf_addElement (mhdf_FileHandle file_handle, const char *name, unsigned int elem_type, mhdf_Status *status) |
Add a new table of element data to the file. More... | |
char ** | mhdf_getElemHandles (mhdf_FileHandle file_handle, unsigned int *count_out, mhdf_Status *status) |
Get the list of element groups in the file. More... | |
void | mhdf_getElemTypeName (mhdf_FileHandle file_handle, const char *elem_handle, char *buffer, size_t buf_len, mhdf_Status *status) |
Get the element type name for a given element group handle. More... | |
const char * | mhdf_node_type_handle (void) |
Get an mhdf_ElemHandle object for the node data. More... | |
const char * | mhdf_set_type_handle (void) |
Return a special element group handle used to specify the set group. More... | |
int | mhdf_isPolyElement (mhdf_FileHandle file_handle, const char *elem_handle, mhdf_Status *status) |
Check if an element group contains polygon or polyhedron. More... | |
void | mhdf_writeHistory (mhdf_FileHandle file_handle, const char **strings, int num_strings, mhdf_Status *status) |
Write the file history as a list of strings. More... | |
char ** | mhdf_readHistory (mhdf_FileHandle file_handle, int *num_strings, mhdf_Status *status) |
Read the file history as a list of strings. More... | |
void | mhdf_getNextStartId (mhdf_FileHandle file, mhdf_index_t *start_id_out, mhdf_Status *status) |
Get start ID that will be assigned to next created dataset. More... | |
|
static |
Definition at line 155 of file file.c.
156 {
157 unsigned long id;
158 hid_t elem_id, conn_id, attr_id, space_id;
159 herr_t rval;
160 int rank;
161 hsize_t dims[2];
162
163 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
164 elem_id = H5Gopen2( group_id, subgroup, H5P_DEFAULT );
165 #else
166 elem_id = H5Gopen( group_id, subgroup );
167 #endif
168 if( elem_id < 0 ) return (herr_t)-1;
169
170 #if defined( H5Dopen_vers ) && H5Dopen_vers > 1
171 conn_id = H5Dopen2( elem_id, datatable, H5P_DEFAULT );
172 #else
173 conn_id = H5Dopen( elem_id, datatable );
174 #endif
175 H5Gclose( elem_id );
176 if( conn_id < 0 ) return (herr_t)-1;
177
178 space_id = H5Dget_space( conn_id );
179 if( space_id < 0 )
180 {
181 H5Dclose( conn_id );
182 return -1;
183 }
184
185 rank = H5Sget_simple_extent_ndims( space_id );
186 if( rank <= 0 || rank > 2 )
187 {
188 H5Dclose( conn_id );
189 H5Sclose( space_id );
190 return -1;
191 }
192
193 rval = H5Sget_simple_extent_dims( space_id, dims, NULL );
194 H5Sclose( space_id );
195 if( rval < 0 )
196 {
197 H5Dclose( conn_id );
198 return -1;
199 }
200
201 attr_id = H5Aopen_name( conn_id, START_ID_ATTRIB );
202 H5Dclose( conn_id );
203 if( attr_id < 0 ) return (herr_t)-1;
204
205 rval = H5Aread( attr_id, H5T_NATIVE_ULONG, &id );
206 H5Aclose( attr_id );
207 if( rval < 0 ) return rval;
208
209 id += dims[0];
210 if( id > *data ) *data = id;
211 return 0;
212 }
References START_ID_ATTRIB.
Referenced by max_id_iter(), and scan_for_max_id().
|
static |
MOAB, a Mesh-Oriented datABase, is a software component for creating, storing and accessing finite element mesh data.
Copyright 2004 Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software.
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
Definition at line 713 of file file.c.
714 {
715 #if defined( H5Gcreate_vers ) && H5Gcreate_vers > 1
716 hid_t handle = H5Gcreate2( file, path, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
717 /* empty statement to avoid compiler warning */
718 if( sz )
719 {
720 }
721 #else
722 hid_t handle = H5Gcreate( file, path, sz );
723 #endif
724 if( handle < 0 )
725 {
726 mhdf_setFail( status, "Failed to create \"%s\" group.", path );
727 return 0;
728 }
729 else
730 {
731 H5Gclose( handle );
732 return 1;
733 }
734 }
References mhdf_setFail().
Referenced by mhdf_createFile().
|
static |
Definition at line 214 of file file.c.
215 {
216 return get_max_id( group_id, name, CONNECTIVITY_NAME, (unsigned long*)data );
217 }
References CONNECTIVITY_NAME, and get_max_id().
Referenced by scan_for_max_id().
void mhdf_addElement | ( | mhdf_FileHandle | file_handle, |
const char * | elem_handle, | ||
unsigned int | named_elem_type, | ||
mhdf_Status * | status | ||
) |
Add a new table of element data to the file.
Add a element group to the file. An element group is the data for a block of elements with the same TSTT type and same number of nodes in their connectivity data. (e.g. all the MBHEX20 elements). This function is also used to create the groups for general polygon data and general polyhedron data. The requirement that all elements have the same number of nodes in their connectivity does not apply for poly(gons|hedra).
file_handle | File in which to create the element type. |
elem_handle | The name to use for the element data. This name is used as an identifier to reference the data for this element type later. The selected name also appears explicitly in the file and therefore should be something descriptive of the element type such as the 'base type' and number of nodes (e.g. "Hex20"). |
named_elem_type | An index into the list of named element types passed to mhdf_createFile . |
status | Passed back status of API call. |
Definition at line 507 of file file.c.
508 {
509 FileHandle* file_ptr = (FileHandle*)file_handle;
510 hid_t group_id, tag_id, enum_id;
511 char *path, *ptr;
512 size_t name_len;
513 herr_t rval;
514 API_BEGIN;
515
516 if( !mhdf_check_valid_file( file_ptr, status ) ) return;
517
518 name_len = mhdf_name_to_path( name, NULL, 0 );
519 name_len += strlen( ELEMENT_GROUP ) + 1;
520 path = (char*)mhdf_malloc( name_len, status );
521 if( !path ) return;
522
523 strcpy( path, ELEMENT_GROUP );
524 ptr = path + strlen( ELEMENT_GROUP );
525 if( !mhdf_path_to_name( name, ptr ) )
526 {
527 mhdf_setFail( status, "Invalid character string in internal file path: \"%s\"\n", name );
528 return;
529 }
530
531 #if defined( H5Gcreate_vers ) && H5Gcreate_vers > 1
532 group_id = H5Gcreate2( file_ptr->hdf_handle, path, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
533 #else
534 group_id = H5Gcreate( file_ptr->hdf_handle, path, 3 );
535 #endif
536 if( group_id < 0 )
537 {
538 mhdf_setFail( status, "Creation of \"%s\" group failed.\n", path );
539 free( path );
540 return;
541 }
542 free( path );
543
544 #if defined( H5Gcreate_vers ) && H5Gcreate_vers > 1
545 tag_id = H5Gcreate2( group_id, DENSE_TAG_SUBGROUP, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
546 #else
547 tag_id = H5Gcreate( group_id, DENSE_TAG_SUBGROUP, 0 );
548 #endif
549 if( tag_id < 0 )
550 {
551 H5Gclose( group_id );
552 mhdf_setFail( status, "Creation of tag subgroup failed.\n" );
553 return;
554 }
555 H5Gclose( tag_id );
556
557 enum_id = get_elem_type_enum( file_ptr, status );
558 if( enum_id < 0 )
559 {
560 H5Gclose( group_id );
561 return;
562 }
563
564 rval = H5Tconvert( H5T_NATIVE_UINT, H5Tget_super( enum_id ), 1, &elem_type, NULL, H5P_DEFAULT );
565 if( rval < 0 )
566 {
567 H5Gclose( group_id );
568 H5Tclose( enum_id );
569 mhdf_setFail( status, "Internal error converting to enum type." );
570 return;
571 }
572
573 rval = mhdf_create_scalar_attrib( group_id, ELEM_TYPE_ATTRIB, enum_id, &elem_type, status );
574 H5Tclose( enum_id );
575 if( rval < 0 )
576 {
577 H5Gclose( group_id );
578 return;
579 }
580
581 H5Gclose( group_id );
582 mhdf_setOkay( status );
583 API_END;
584 }
References API_BEGIN, API_END, DENSE_TAG_SUBGROUP, ELEM_TYPE_ATTRIB, ELEMENT_GROUP, get_elem_type_enum(), struct_FileHandle::hdf_handle, mhdf_check_valid_file(), mhdf_create_scalar_attrib(), mhdf_malloc(), mhdf_name_to_path(), mhdf_path_to_name(), mhdf_setFail(), and mhdf_setOkay().
Referenced by moab::WriteHDF5::create_elem_table().
int mhdf_checkOpenHandles | ( | mhdf_FileHandle | handle, |
mhdf_Status * | status | ||
) |
Definition at line 409 of file file.c.
410 {
411 FileHandle* file_ptr;
412 int result;
413 API_BEGIN;
414
415 file_ptr = (FileHandle*)( handle );
416 if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
417
418 /* Check for open handles. HDF5 will not actually close the
419 file until all handles are closed. */
420 result = H5Fget_obj_count( file_ptr->hdf_handle, H5F_OBJ_ALL );
421 if( result != 1 )
422 {
423 mhdf_setFail( status,
424 "Cannot close file with open handles: "
425 "%d file, %d data, %d group, %d type, %d attr\n",
426 H5Fget_obj_count( file_ptr->hdf_handle, H5F_OBJ_FILE ) - 1,
427 H5Fget_obj_count( file_ptr->hdf_handle, H5F_OBJ_DATASET ),
428 H5Fget_obj_count( file_ptr->hdf_handle, H5F_OBJ_GROUP ),
429 H5Fget_obj_count( file_ptr->hdf_handle, H5F_OBJ_DATATYPE ),
430 H5Fget_obj_count( file_ptr->hdf_handle, H5F_OBJ_ATTR ) );
431 return result - 1;
432 }
433
434 API_END_H( 0 );
435 return 0;
436 }
References API_BEGIN, API_END_H, struct_FileHandle::hdf_handle, mhdf_check_valid_file(), and mhdf_setFail().
Referenced by mhdf_closeFile().
void mhdf_closeData | ( | mhdf_FileHandle | file, |
hid_t | handle, | ||
mhdf_Status * | status | ||
) |
Common close function for all data handle types.
Close an hid_t-type handle returned from any of the following functions. Any hid_t passed-back or returned must be closed via this function to avoid resource loss.
file | The file the object pointed to by the passed data handled exists int. |
handle | The data object to close. |
status | Passed back status of API call. |
Definition at line 470 of file file.c.
471 {
472 FileHandle* file_ptr;
473 herr_t rval = -1;
474
475 file_ptr = (FileHandle*)( file );
476 if( !mhdf_check_valid_file( file_ptr, status ) ) return;
477
478 switch( H5Iget_type( handle ) )
479 {
480 case H5I_GROUP:
481 rval = H5Gclose( handle );
482 break;
483 case H5I_DATATYPE:
484 rval = H5Tclose( handle );
485 break;
486 case H5I_DATASPACE:
487 rval = H5Sclose( handle );
488 break;
489 case H5I_DATASET:
490 rval = H5Dclose( handle );
491 break;
492 default:
493 rval = -1;
494 }
495
496 if( rval < 0 )
497 {
498 mhdf_setFail( status, "H5Xclose failed. Invalid handle?\n" );
499 }
500 else
501 {
502 file_ptr->open_handle_count--;
503 mhdf_setOkay( status );
504 }
505 }
References mhdf_check_valid_file(), mhdf_setFail(), mhdf_setOkay(), and struct_FileHandle::open_handle_count.
Referenced by check_valid_adjacencies(), check_valid_elem_conn(), check_valid_poly_conn(), check_valid_sets(), check_valid_tag(), check_valid_var_len_tag(), moab::WriteHDF5Parallel::create_adjacency_tables(), moab::WriteHDF5::create_elem_table(), moab::WriteHDF5Parallel::create_node_table(), moab::WriteHDF5::create_set_meta(), moab::WriteHDF5::create_set_tables(), moab::WriteHDF5::create_tag(), moab::ReadHDF5::find_sets_containing(), get_elem_desc(), moab::ReadHDF5::get_tagged_entities(), moab::ReadHDF5::load_file_impl(), moab::ReadHDF5::load_file_partial(), main(), mhdf_getFileSummary(), moab::ReadHDF5::read_all_set_meta(), moab::ReadHDF5::read_node_adj_elems(), moab::ReadHDF5::read_nodes(), moab::ReadHDF5::read_tag(), moab::ReadHDF5::read_tag_values_all(), moab::ReadHDF5::search_tag_values(), moab::WriteHDF5::serial_create_file(), moab::WriteHDF5::write_adjacencies(), moab::WriteHDF5::write_dense_tag(), moab::WriteHDF5::write_elems(), moab::WriteHDF5::write_nodes(), moab::WriteHDF5::write_sets(), moab::WriteHDF5::write_sparse_tag(), and moab::WriteHDF5::write_var_len_tag().
void mhdf_closeFile | ( | mhdf_FileHandle | handle, |
mhdf_Status * | status | ||
) |
Close the file.
handle | The file to close. |
status | Passed back status of API call. |
Definition at line 438 of file file.c.
439 {
440 FileHandle* file_ptr;
441 API_BEGIN;
442
443 file_ptr = (FileHandle*)( handle );
444 if( !mhdf_check_valid_file( file_ptr, status ) ) return;
445 /*
446 if (file_ptr->open_handle_count)
447 {
448 mhdf_setError( status, "Cannot close file with %d open data handles.",
449 file_ptr->open_handle_count );
450 return;
451 }
452 */
453
454 /* Check for open handles. HDF5 will not actually close the
455 file until all handles are closed. */
456 if( mhdf_checkOpenHandles( handle, status ) ) return;
457
458 if( 0 > H5Fclose( file_ptr->hdf_handle ) )
459 {
460 mhdf_setFail( status, "H5FClose failed. Invalid handle?" );
461 return;
462 }
463
464 memset( file_ptr, 0, sizeof( FileHandle ) );
465 free( file_ptr );
466 mhdf_setOkay( status );
467 API_END_H( -1 );
468 }
References API_BEGIN, API_END_H, struct_FileHandle::hdf_handle, mhdf_check_valid_file(), mhdf_checkOpenHandles(), mhdf_setFail(), and mhdf_setOkay().
Referenced by moab::ReadHDF5::clean_up_read(), iMOAB_ReadHeaderInfo(), main(), moab::WriteHDF5Parallel::parallel_create_file(), moab::ReadHDF5::set_up_read(), and moab::WriteHDF5::write_file().
int mhdf_countOpenHandles | ( | mhdf_FileHandle | file_handle | ) |
Get number of open HDF5 objects from file.
Definition at line 150 of file file.c.
151 {
152 return H5Fget_obj_count( ( (FileHandle*)file_handle )->hdf_handle, H5F_OBJ_ALL );
153 }
Referenced by moab::CheckOpenReadHDF5Handles::~CheckOpenReadHDF5Handles(), and moab::CheckOpenWriteHDF5Handles::~CheckOpenWriteHDF5Handles().
mhdf_FileHandle mhdf_createFile | ( | const char * | filename, |
int | overwrite, | ||
const char ** | elem_type_list, | ||
size_t | elem_type_list_len, | ||
hid_t | id_type, | ||
mhdf_Status * | status | ||
) |
Create a new file.
Create a new HDF mesh file. This handle must be closed with mhdf_closeFile
to avoid resource loss.
filename | The path and name of the file to create |
overwrite | If zero, will fail if the specified file already exists. If non-zero, will overwrite an existing file. |
elem_type_list | The list of element types that will be stored in the file. If the element name exits as a pre- defined constant (mhdf_type), that constant should be used. If a constant does not exist for the type, a similar naming pattern should be used (accepted name for type, first character uppercase, subsequent characters lowercase.) The element type index passed to mhdf_addElement is then an index into this list. The array may contain null entries to allow the caller some control over the assigned indices without creating dummy types which may confuse readers. |
elem_type_list_len | The length of elem_type_list . |
id_type | Type to use when creating datasets containing file IDs |
status | Passed back status of API call. |
Definition at line 37 of file file.c.
43 {
44 FileHandle* file_ptr;
45 unsigned int flags;
46 unsigned char idx;
47 size_t i;
48 hid_t enum_id, group_id;
49 int rval;
50 API_BEGIN;
51
52 if( elem_list_len > 255 )
53 {
54 mhdf_setFail( status, "Element type list too long." );
55 return NULL;
56 }
57 mhdf_setOkay( status );
58
59 /* Create struct to hold working data */
60 file_ptr = mhdf_alloc_FileHandle( 0, id_type, status );
61 if( !file_ptr ) return NULL;
62
63 /* Create the file */
64 flags = overwrite ? H5F_ACC_TRUNC : H5F_ACC_EXCL;
65 file_ptr->hdf_handle = H5Fcreate( filename, flags, H5P_DEFAULT, H5P_DEFAULT );
66 if( file_ptr->hdf_handle < 0 )
67 {
68 mhdf_setFail( status, "Failed to create file \"%s\"", filename );
69 free( file_ptr );
70 return NULL;
71 }
72
73 /* Create file structure */
74 if( !make_hdf_group( ROOT_GROUP, file_ptr->hdf_handle, 6, status ) ||
75 !make_hdf_group( TAG_GROUP, file_ptr->hdf_handle, 0, status ) ||
76 !make_hdf_group( ELEMENT_GROUP, file_ptr->hdf_handle, 8, status ) ||
77 !make_hdf_group( NODE_GROUP, file_ptr->hdf_handle, 3, status ) ||
78 !make_hdf_group( SET_GROUP, file_ptr->hdf_handle, 5, status ) ||
79 !make_hdf_group( NODE_TAG_GROUP, file_ptr->hdf_handle, 0, status ) ||
80 !make_hdf_group( SET_TAG_GROUP, file_ptr->hdf_handle, 0, status ) )
81 {
82 H5Fclose( file_ptr->hdf_handle );
83 free( file_ptr );
84 return NULL;
85 }
86
87 /* Store the max ID as an attribite on the /tstt/ group */
88 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
89 group_id = H5Gopen2( file_ptr->hdf_handle, ROOT_GROUP, H5P_DEFAULT );
90 #else
91 group_id = H5Gopen( file_ptr->hdf_handle, ROOT_GROUP );
92 #endif
93 rval = mhdf_create_scalar_attrib( group_id, MAX_ID_ATTRIB, H5T_NATIVE_ULONG, &file_ptr->max_id, status );
94 H5Gclose( group_id );
95 if( !rval )
96 {
97 H5Fclose( file_ptr->hdf_handle );
98 free( file_ptr );
99 return NULL;
100 }
101
102 /* Create the type name list in file */
103 enum_id = H5Tenum_create( H5T_NATIVE_UCHAR );
104 if( enum_id < 0 )
105 {
106 mhdf_setFail( status, "Failed to store elem type list." );
107 H5Fclose( file_ptr->hdf_handle );
108 free( file_ptr );
109 return NULL;
110 }
111 for( i = 0; i < elem_list_len; ++i )
112 {
113 if( !elem_type_list[i] || !*elem_type_list[i] ) continue;
114
115 idx = (unsigned char)i;
116 if( H5Tenum_insert( enum_id, elem_type_list[i], &idx ) < 0 )
117 {
118 mhdf_setFail( status, "Failed to store elem type list." );
119 H5Fclose( file_ptr->hdf_handle );
120 free( file_ptr );
121 return NULL;
122 }
123 }
124 #if defined( H5Tcommit_vers ) && H5Tcommit_vers > 1
125 if( H5Tcommit2( file_ptr->hdf_handle, TYPE_ENUM_PATH, enum_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT ) < 0 )
126 #else
127 if( H5Tcommit( file_ptr->hdf_handle, TYPE_ENUM_PATH, enum_id ) < 0 )
128 #endif
129 {
130 mhdf_setFail( status, "Failed to store elem type list." );
131 H5Fclose( file_ptr->hdf_handle );
132 free( file_ptr );
133 return NULL;
134 }
135 H5Tclose( enum_id );
136
137 API_END_H( 1 );
138 return file_ptr;
139 }
References API_BEGIN, API_END_H, ELEMENT_GROUP, struct_FileHandle::hdf_handle, make_hdf_group(), struct_FileHandle::max_id, MAX_ID_ATTRIB, mhdf_alloc_FileHandle(), mhdf_create_scalar_attrib(), mhdf_setFail(), mhdf_setOkay(), NODE_GROUP, NODE_TAG_GROUP, ROOT_GROUP, SET_GROUP, SET_TAG_GROUP, TAG_GROUP, and TYPE_ENUM_PATH.
Referenced by moab::WriteHDF5Parallel::parallel_create_file(), and moab::WriteHDF5::serial_create_file().
char** mhdf_getElemHandles | ( | mhdf_FileHandle | file_handle, |
unsigned int * | count_out, | ||
mhdf_Status * | status | ||
) |
Get the list of element groups in the file.
Get the list of element groups in the file. An element group is the data for a block of elements with the same TSTT type and same number of nodes in their connectivity data. (e.g. all the MBHEX20 elements). This function is also used to retrieve the groups for general polygon data and general polyhedron data. The requirement that all elements have the same number of nodes in their connectivity does not apply for poly(gons|hedra).
file_handle | The file. |
count_out | Memory location at which to store the length of the returned array. |
status | Passed back status of API call. |
Definition at line 586 of file file.c.
587 {
588 hsize_t count, length, i;
589 char** buffer;
590 char* current;
591 hid_t group_id;
592 herr_t rval;
593 ssize_t rlen = 0;
594 size_t remaining;
595 FileHandle* file_ptr = (FileHandle*)file_handle;
596 if( !mhdf_check_valid_file( file_ptr, status ) ) return NULL;
597
598 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
599 group_id = H5Gopen2( file_ptr->hdf_handle, ELEMENT_GROUP, H5P_DEFAULT );
600 #else
601 group_id = H5Gopen( file_ptr->hdf_handle, ELEMENT_GROUP );
602 #endif
603 if( group_id < 0 )
604 {
605 mhdf_setFail( status, "Invalid file -- element group does not exist." );
606 return NULL;
607 }
608
609 rval = H5Gget_num_objs( group_id, &count );
610 if( rval < 0 )
611 {
612 H5Gclose( group_id );
613 mhdf_setFail( status, "Internal error calling H5Gget_num_objs." );
614 return NULL;
615 }
616 *count_out = count;
617
618 for( i = 0; i < count; ++i )
619 {
620 rlen += H5Gget_objname_by_idx( group_id, i, NULL, 0 ) + 1;
621 }
622
623 length = count * sizeof( char* ) + rlen;
624 buffer = (char**)mhdf_malloc( length, status );
625 if( !buffer )
626 {
627 H5Gclose( group_id );
628 return NULL;
629 }
630 current = (char*)( buffer + count );
631 remaining = rlen;
632
633 for( i = 0; i < count; ++i )
634 {
635 buffer[i] = current;
636 rlen = H5Gget_objname_by_idx( group_id, i, current, remaining ) + 1;
637 if( rlen < 0 )
638 {
639 H5Gclose( group_id );
640 free( buffer );
641 mhdf_setFail( status, "Internal error calling H5Gget_objname_by_idx." );
642 return NULL;
643 }
644
645 mhdf_path_to_name( current, current );
646 remaining -= rlen;
647 current += rlen;
648 }
649
650 H5Gclose( group_id );
651 mhdf_setOkay( status );
652 return buffer;
653 }
References buffer, ELEMENT_GROUP, struct_FileHandle::hdf_handle, length(), mhdf_check_valid_file(), mhdf_malloc(), mhdf_path_to_name(), mhdf_setFail(), and mhdf_setOkay().
Referenced by main(), and mhdf_getFileSummary().
void mhdf_getElemName | ( | mhdf_FileHandle | file_handle, |
unsigned int | type_index, | ||
char * | buffer, | ||
size_t | buffer_size, | ||
mhdf_Status * | status | ||
) |
Given an element type Id, get the name. Fails if buffer is not of sufficient size.
file_handle | The file. |
type_index | The type index. Corresponds to indices into the element type list passed to mhdf_createFile. |
buffer | The buffer into which to copy the name. |
buffer_size | The length of buffer . |
status | Passed back status of API call. |
Definition at line 368 of file file.c.
373 {
374 FileHandle* file_ptr;
375 herr_t rval;
376 hid_t enum_id;
377 API_BEGIN;
378
379 if( type_index > 255 )
380 {
381 mhdf_setFail( status, "Type index out of bounds." );
382 return;
383 }
384
385 file_ptr = (FileHandle*)( file_handle );
386 if( !mhdf_check_valid_file( file_ptr, status ) ) return;
387
388 enum_id = get_elem_type_enum( file_ptr, status );
389 if( enum_id < 0 ) return;
390
391 rval = H5Tconvert( H5T_NATIVE_UINT, H5Tget_super( enum_id ), 1, &type_index, NULL, H5P_DEFAULT );
392 if( rval < 0 )
393 {
394 H5Tclose( enum_id );
395 mhdf_setFail( status, "Internal error converting to enum type." );
396 return;
397 }
398
399 rval = H5Tenum_nameof( enum_id, &type_index, buffer, buf_size );
400 H5Tclose( enum_id );
401 if( rval < 0 )
402 mhdf_setFail( status, "H5Tenum_nameof failed. Invalid type index?" );
403 else
404 mhdf_setOkay( status );
405
406 API_END;
407 }
References API_BEGIN, API_END, buffer, get_elem_type_enum(), mhdf_check_valid_file(), mhdf_setFail(), and mhdf_setOkay().
void mhdf_getElemTypeName | ( | mhdf_FileHandle | file_handle, |
const char * | elem_handle, | ||
char * | buffer, | ||
size_t | buf_len, | ||
mhdf_Status * | status | ||
) |
Get the element type name for a given element group handle.
Fails if name is longer than buf_len
.
file_handle | The file. |
elem_handle | One of the group names passed back from mhdf_getElemHandles |
buffer | A buffer to copy the name into. |
buf_len | The length of buffer . |
status | Passed back status of API call. |
Definition at line 655 of file file.c.
660 {
661 FileHandle* file_ptr;
662 hid_t elem_id, type_id, attr_id;
663 char bytes[16];
664 herr_t rval;
665 API_BEGIN;
666
667 if( NULL == buffer || buf_len < 2 )
668 {
669 mhdf_setFail( status, "invalid input" );
670 return;
671 }
672 buffer[0] = '\0';
673
674 file_ptr = (FileHandle*)( file_handle );
675 if( !mhdf_check_valid_file( file_ptr, status ) ) return;
676
677 elem_id = mhdf_elem_group_from_handle( file_ptr, elem_handle, status );
678 if( elem_id < 0 ) return;
679
680 attr_id = H5Aopen_name( elem_id, ELEM_TYPE_ATTRIB );
681 H5Gclose( elem_id );
682 if( attr_id < 0 )
683 {
684 mhdf_setFail( status, "Missing element type attribute. Invalid file." );
685 return;
686 }
687
688 type_id = H5Aget_type( attr_id );
689 assert( type_id > 0 );
690
691 rval = H5Aread( attr_id, type_id, bytes );
692 H5Aclose( attr_id );
693 if( rval < 0 )
694 {
695 H5Tclose( type_id );
696 mhdf_setFail( status, "Failed to read element type attribute. Invalid file." );
697 return;
698 }
699
700 rval = H5Tenum_nameof( type_id, bytes, buffer, buf_len );
701 H5Tclose( type_id );
702 if( rval < 0 )
703 {
704 mhdf_setFail( status, "Invalid datatype for element type attribute. Invalid file." );
705 return;
706 }
707
708 mhdf_setOkay( status );
709 API_END;
710 return;
711 }
References API_BEGIN, API_END, buffer, ELEM_TYPE_ATTRIB, mhdf_check_valid_file(), mhdf_elem_group_from_handle(), mhdf_setFail(), and mhdf_setOkay().
Referenced by get_elem_desc(), and main().
void mhdf_getNextStartId | ( | mhdf_FileHandle | file, |
mhdf_index_t * | start_id_out, | ||
mhdf_Status * | status | ||
) |
Get start ID that will be assigned to next created dataset.
Get the first_id parameter that will be returned from the next call to any of mhdf_createNodeCoords, mhdf_createConnectivity, mhdf_createPolyConnectivity, or mhdf_createSetMeta
Definition at line 925 of file file.c.
926 {
927 FileHandle* file_ptr = (FileHandle*)file;
928 API_BEGIN;
929
930 mhdf_setOkay( status );
931 if( mhdf_check_valid_file( file_ptr, status ) ) *start_id_out = file_ptr->max_id + 1;
932
933 API_END;
934 }
References API_BEGIN, API_END, struct_FileHandle::max_id, mhdf_check_valid_file(), and mhdf_setOkay().
int mhdf_isPolyElement | ( | mhdf_FileHandle | file_handle, |
const char * | elem_handle, | ||
mhdf_Status * | status | ||
) |
Check if an element group contains polygon or polyhedron.
Check if an element group contains general polygon or polyhedrons rather than typically fixed-connectivity elements.
file_handle | The file. |
elem_handle | The element group. |
status | Passed back status of API call. |
Definition at line 748 of file file.c.
749 {
750 FileHandle* file_ptr;
751 hid_t elem_id;
752 int rval;
753 API_BEGIN;
754
755 file_ptr = (FileHandle*)( file_handle );
756 if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
757
758 elem_id = mhdf_elem_group_from_handle( file_ptr, elem_handle, status );
759 if( elem_id < 0 ) return -1;
760
761 mhdf_setOkay( status );
762 rval = mhdf_is_in_group( elem_id, POLY_INDEX_NAME, status );
763 H5Gclose( elem_id );
764 API_END;
765 return rval;
766 }
References API_BEGIN, API_END, mhdf_check_valid_file(), mhdf_elem_group_from_handle(), mhdf_is_in_group(), mhdf_setOkay(), and POLY_INDEX_NAME.
Referenced by get_elem_desc().
const char* mhdf_node_type_handle | ( | void | ) |
Get an mhdf_ElemHandle object for the node data.
MOAB, a Mesh-Oriented datABase, is a software component for creating, storing and accessing finite element mesh data.
Copyright 2004 Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains certain rights in this software.
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. MHDF API for reading/writing MOAB-format HDF5 mesh files. Error handling Element group handle
Definition at line 736 of file file.c.
737 {
738 static const char rval[] = "nodes";
739 return rval;
740 }
Referenced by check_valid_tag(), main(), mhdf_createAdjacency(), mhdf_createDenseTagData(), mhdf_getFileSummary(), mhdf_haveAdjacency(), mhdf_haveDenseTag(), mhdf_openAdjacency(), mhdf_openDenseTagData(), moab::WriteHDF5::ExportSet::name(), moab::ReadHDF5::read_tag(), moab::ReadHDF5::read_tag_values_all(), moab::ReadHDF5::read_tag_values_partial(), moab::ReadHDF5::search_tag_values(), and moab::WriteHDF5::serial_create_file().
mhdf_FileHandle mhdf_openFile | ( | const char * | filename, |
int | writable, | ||
unsigned long * | max_id, | ||
hid_t | id_type, | ||
mhdf_Status * | status | ||
) |
Open an existing file.
Open an existing HDF mesh file. This handle must be closed with mhdf_closeFile
to avoid resource loss.
filename | The path and name of the file to open |
writable | If non-zero, open read-write. Otherwise read-only. |
status | Passed back status of API call. |
max_id | Used to pass back the maximum global ID used in the file. Provided as an indication to the caller of the size of the mesh. This parameter is optional. NULL may be passed. |
id_type | Type to use when creating datasets containing file IDs |
Definition at line 141 of file file.c.
146 {
147 return mhdf_openFileWithOpt( filename, writeable, max_id_out, id_type, H5P_DEFAULT, status );
148 }
References mhdf_openFileWithOpt().
Referenced by iMOAB_ReadHeaderInfo(), main(), and moab::ReadHDF5::set_up_read().
mhdf_FileHandle mhdf_openFileWithOpt | ( | const char * | filename, |
int | writable, | ||
unsigned long * | max_id, | ||
hid_t | id_type, | ||
hid_t | options, | ||
mhdf_Status * | status | ||
) |
Open an existing file with options.
Open an existing HDF mesh file. This handle must be closed with mhdf_closeFile
to avoid resource loss. This function allows the calling application to specify the HDF5 access property list that is passed to the HDF5 H5Fopen API. If this is passed as H5P_DEFAULT, the behavior is the same as mhdf_openFile . This argument is typically used to specify a parallel context for for writing the file in parallel.
filename | The path and name of the file to open |
writable | If non-zero, open read-write. Otherwise read-only. |
status | Passed back status of API call. |
max_id | Used to pass back the maximum global ID used in the file. Provided as an indication to the caller of the size of the mesh. This parameter is optional. NULL may be passed. |
options | The HDF5 access property list to use when opening the file. See the HDF5 documentation for H5Fopen. |
id_type | Type to use when creating datasets containing file IDs |
Definition at line 277 of file file.c.
283 {
284 FileHandle* file_ptr;
285 unsigned int flags;
286 hid_t group_id;
287 int check_is_hdf5 = 1;
288 #ifdef MOAB_HAVE_HDF5_PARALLEL
289 herr_t err;
290 MPI_Comm comm;
291 MPI_Info info;
292 #endif
293 API_BEGIN;
294
295 /* Check if file is HDF5 */
296 /* Don't do this because it can't handle MPI-IO driver code that
297 passes options via prefixes on the file name. */
298 #ifdef MOAB_HAVE_HDF5_PARALLEL
299 if( access_prop != H5P_DEFAULT )
300 {
301 err = H5Pget_fapl_mpio( access_prop, &comm, &info );
302 if( err >= 0 )
303 {
304 check_is_hdf5 = 0;
305 /* MPI Documentation is inconsistent with regards to whether
306 or not the above call dup's these, but my testing with 1.8.3
307 indicates that at least for that version they are not.
308 MPI_Comm_free(&comm);
309 MPI_Info_free(&info); */
310 }
311 }
312 #endif
313 if( check_is_hdf5 && H5Fis_hdf5( filename ) <= 0 )
314 {
315 mhdf_setFail( status, "%s: File is not HDF5", filename );
316 return NULL;
317 }
318
319 /* Create struct to hold working data */
320 file_ptr = mhdf_alloc_FileHandle( 0, id_type, status );
321 if( !file_ptr )
322 {
323 mhdf_setFail( status, "Memory allocation failed" );
324 return NULL;
325 }
326
327 /* Create the file */
328 flags = writable ? H5F_ACC_RDWR : H5F_ACC_RDONLY;
329 file_ptr->hdf_handle = H5Fopen( filename, flags, access_prop );
330 if( file_ptr->hdf_handle < 0 )
331 {
332 mhdf_setFail( status, "Failed to open file \"%s\"", filename );
333 free( file_ptr );
334 return NULL;
335 }
336
337 /* Check for TSTT data in file */
338 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
339 group_id = H5Gopen2( file_ptr->hdf_handle, ROOT_GROUP, H5P_DEFAULT );
340 #else
341 group_id = H5Gopen( file_ptr->hdf_handle, ROOT_GROUP );
342 #endif
343 if( group_id < 0 )
344 {
345 mhdf_setFail( status, "Invalid file \"%s\"\n", filename );
346 H5Fclose( file_ptr->hdf_handle );
347 free( file_ptr );
348 return NULL;
349 }
350 H5Gclose( group_id );
351
352 /* Get max id */
353 if( !scan_for_max_id( file_ptr, status ) )
354 {
355 H5Fclose( file_ptr->hdf_handle );
356 mhdf_setFail( status, "Internal error reading file" );
357 free( file_ptr );
358 return NULL;
359 }
360
361 if( max_id_out ) *max_id_out = file_ptr->max_id;
362
363 mhdf_setOkay( status );
364 API_END_H( 1 );
365 return file_ptr;
366 }
References API_BEGIN, API_END_H, struct_FileHandle::hdf_handle, struct_FileHandle::max_id, mhdf_alloc_FileHandle(), mhdf_setFail(), mhdf_setOkay(), ROOT_GROUP, and scan_for_max_id().
Referenced by mhdf_openFile(), moab::WriteHDF5Parallel::parallel_create_file(), and moab::ReadHDF5::set_up_read().
char** mhdf_readHistory | ( | mhdf_FileHandle | file, |
int * | num_records_out, | ||
mhdf_Status * | status | ||
) |
Read the file history as a list of strings.
Each entry is composed of four strings: application, version, date, and time.
Strings and array are allocated with malloc
. Caller must release them by calling free
file | The file. |
num_records_out | The length of the returned array. |
status | Passed back status of API call. |
Definition at line 823 of file file.c.
824 {
825 FileHandle* file_ptr;
826 hid_t data_id, type_id, space_id, group_id;
827 hsize_t dim;
828 herr_t rval;
829 char** array;
830 API_BEGIN;
831
832 file_ptr = (FileHandle*)( file_handle );
833 if( !mhdf_check_valid_file( file_ptr, status ) ) return NULL;
834
835 /* check if file contains history data */
836 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
837 group_id = H5Gopen2( file_ptr->hdf_handle, ROOT_GROUP, H5P_DEFAULT );
838 #else
839 group_id = H5Gopen( file_ptr->hdf_handle, ROOT_GROUP );
840 #endif
841 if( group_id < 0 )
842 {
843 mhdf_setFail( status, "Could not open root group. Invalid file." );
844 return NULL;
845 }
846
847 rval = mhdf_is_in_group( group_id, HISTORY_NAME, status );
848 if( rval < 1 )
849 {
850 H5Gclose( group_id );
851 *num_strings = 0;
852 if( 0 == rval ) mhdf_setOkay( status );
853 return NULL;
854 }
855
856 #if defined( H5Dopen_vers ) && H5Dopen_vers > 1
857 data_id = H5Dopen2( group_id, HISTORY_NAME, H5P_DEFAULT );
858 #else
859 data_id = H5Dopen( group_id, HISTORY_NAME );
860 #endif
861 H5Gclose( group_id );
862 if( data_id < 0 )
863 {
864 mhdf_setFail( status, "Failed to open \"%s\".", HISTORY_PATH );
865 return NULL;
866 }
867
868 space_id = H5Dget_space( data_id );
869 if( space_id < 0 )
870 {
871 H5Dclose( data_id );
872 mhdf_setFail( status, "Internal error calling H5Dget_space." );
873 return NULL;
874 }
875
876 if( 1 != H5Sget_simple_extent_ndims( space_id ) || 1 != H5Sget_simple_extent_dims( space_id, &dim, NULL ) )
877 {
878 H5Dclose( data_id );
879 mhdf_setFail( status, "Invalid dimension for \"%s\".", HISTORY_PATH );
880 return NULL;
881 }
882 H5Sclose( space_id );
883
884 if( 0 == dim )
885 {
886 H5Dclose( data_id );
887 *num_strings = 0;
888 mhdf_setOkay( status );
889 return NULL;
890 }
891
892 array = (char**)mhdf_malloc( dim * sizeof( char* ), status );
893 if( !array )
894 {
895 H5Dclose( data_id );
896 return NULL;
897 }
898
899 type_id = H5Tcopy( H5T_C_S1 );
900 if( type_id < 0 || H5Tset_size( type_id, H5T_VARIABLE ) < 0 )
901 {
902 H5Dclose( data_id );
903 if( type_id >= 0 ) H5Tclose( type_id );
904 mhdf_setFail( status, "Could not create variable length string type." );
905 free( array );
906 return NULL;
907 }
908
909 rval = H5Dread( data_id, type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, array );
910 H5Tclose( type_id );
911 H5Dclose( data_id );
912 if( rval < 0 )
913 {
914 free( array );
915 mhdf_setFail( status, "H5Dread failed." );
916 return NULL;
917 }
918
919 *num_strings = dim;
920 mhdf_setOkay( status );
921 API_END;
922 return array;
923 }
References API_BEGIN, API_END, dim, struct_FileHandle::hdf_handle, HISTORY_NAME, HISTORY_PATH, mhdf_check_valid_file(), mhdf_is_in_group(), mhdf_malloc(), mhdf_setFail(), mhdf_setOkay(), and ROOT_GROUP.
Referenced by moab::ReadHDF5::read_qa().
const char* mhdf_set_type_handle | ( | void | ) |
Return a special element group handle used to specify the set group.
Definition at line 742 of file file.c.
743 {
744 static const char rval[] = "sets";
745 return rval;
746 }
Referenced by check_valid_tag(), mhdf_createDenseTagData(), mhdf_getFileSummary(), mhdf_haveDenseTag(), mhdf_openDenseTagData(), moab::WriteHDF5::ExportSet::name(), moab::ReadHDF5::read_tag(), moab::ReadHDF5::read_tag_values_all(), moab::ReadHDF5::read_tag_values_partial(), and moab::ReadHDF5::search_tag_values().
void mhdf_writeHistory | ( | mhdf_FileHandle | file, |
const char ** | strings, | ||
int | num_strings, | ||
mhdf_Status * | status | ||
) |
Write the file history as a list of strings.
Each entry is composed of four strings: application, version, date, and time.
file | The file. |
strings | An array of null-terminated strings. |
num_strings | The length of strings |
status | Passed back status of API call. |
Definition at line 768 of file file.c.
769 {
770 FileHandle* file_ptr;
771 hid_t data_id, type_id, space_id;
772 hsize_t dim = (hsize_t)num_strings;
773 herr_t rval;
774 API_BEGIN;
775
776 file_ptr = (FileHandle*)( file_handle );
777 if( !mhdf_check_valid_file( file_ptr, status ) ) return;
778
779 type_id = H5Tcopy( H5T_C_S1 );
780 if( type_id < 0 || H5Tset_size( type_id, H5T_VARIABLE ) < 0 )
781 {
782 if( type_id >= 0 ) H5Tclose( type_id );
783 mhdf_setFail( status, "Could not create variable length string type." );
784 return;
785 }
786
787 space_id = H5Screate_simple( 1, &dim, NULL );
788 if( space_id < 0 )
789 {
790 H5Tclose( type_id );
791 mhdf_setFail( status, "H5Screate_simple failed." );
792 return;
793 }
794
795 #if defined( H5Dcreate_vers ) && H5Dcreate_vers > 1
796 data_id =
797 H5Dcreate2( file_ptr->hdf_handle, HISTORY_PATH, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
798 #else
799 data_id = H5Dcreate( file_ptr->hdf_handle, HISTORY_PATH, type_id, space_id, H5P_DEFAULT );
800 #endif
801 H5Sclose( space_id );
802 if( data_id < 0 )
803 {
804 H5Tclose( type_id );
805 mhdf_setFail( status, "Failed to create \"%s\".", HISTORY_PATH );
806 return;
807 }
808
809 rval = H5Dwrite( data_id, type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, strings );
810 H5Dclose( data_id );
811 H5Tclose( type_id );
812 if( rval < 0 )
813 {
814 H5Gunlink( file_ptr->hdf_handle, HISTORY_PATH );
815 mhdf_setFail( status, "Failed to write history data." );
816 return;
817 }
818
819 mhdf_setOkay( status );
820 API_END;
821 }
References API_BEGIN, API_END, dim, struct_FileHandle::hdf_handle, HISTORY_PATH, mhdf_check_valid_file(), mhdf_setFail(), and mhdf_setOkay().
Referenced by moab::WriteHDF5::write_qa().
|
static |
Definition at line 219 of file file.c.
220 {
221 hid_t group_id;
222 herr_t rval;
223
224 /* Check for new format, with max_id as attrib of root group */
225 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
226 group_id = H5Gopen2( file_ptr->hdf_handle, ROOT_GROUP, H5P_DEFAULT );
227 #else
228 group_id = H5Gopen( file_ptr->hdf_handle, ROOT_GROUP );
229 #endif
230 if( group_id < 0 )
231 {
232 mhdf_setFail( status, "Internal error - invalid file." );
233 return 0;
234 }
235 if( mhdf_read_scalar_attrib( group_id, MAX_ID_ATTRIB, H5T_NATIVE_ULONG, &file_ptr->max_id, status ) )
236 {
237 H5Gclose( group_id );
238 return 1;
239 }
240
241 /* Didn't find it, scan the elements group */
242 rval = H5Giterate( group_id, ELEMENT_GROUP_NAME, 0, &max_id_iter, &file_ptr->max_id );
243 if( rval )
244 {
245 H5Gclose( group_id );
246 mhdf_setFail( status, "Internal error -- invalid file." );
247 return 0;
248 }
249
250 /* Check node table too */
251 rval = get_max_id( group_id, NODE_GROUP_NAME, "coordinates", (unsigned long*)( &file_ptr->max_id ) );
252 if( rval )
253 {
254 H5Gclose( group_id );
255 mhdf_setFail( status, "Internal error -- invalid file." );
256 return 0;
257 }
258
259 /* Check set table, if it exists */
260 rval = mhdf_is_in_group( group_id, SET_GROUP_NAME, status );
261 if( rval < 1 )
262 {
263 H5Gclose( group_id );
264 return !rval;
265 }
266 rval = get_max_id( group_id, SET_GROUP_NAME, SET_META_NAME, (unsigned long*)( &file_ptr->max_id ) );
267 H5Gclose( group_id );
268 if( rval )
269 {
270 mhdf_setFail( status, "Internal error -- invalid file." );
271 return 0;
272 }
273
274 return 1;
275 }
References ELEMENT_GROUP_NAME, get_max_id(), struct_FileHandle::hdf_handle, struct_FileHandle::max_id, MAX_ID_ATTRIB, max_id_iter(), mhdf_is_in_group(), mhdf_read_scalar_attrib(), mhdf_setFail(), NODE_GROUP_NAME, ROOT_GROUP, SET_GROUP_NAME, and SET_META_NAME.
Referenced by mhdf_openFileWithOpt().