[MOAB-dev] r1588 - in MOAB/trunk/mhdf: include src
kraftche at mcs.anl.gov
kraftche at mcs.anl.gov
Tue Feb 5 19:00:42 CST 2008
Author: kraftche
Date: 2008-02-05 19:00:42 -0600 (Tue, 05 Feb 2008)
New Revision: 1588
Modified:
MOAB/trunk/mhdf/include/mhdf.h
MOAB/trunk/mhdf/src/names-and-paths.h
MOAB/trunk/mhdf/src/tags.c
Log:
Low-level support for variable-length tag save/restore.
Modified: MOAB/trunk/mhdf/include/mhdf.h
===================================================================
--- MOAB/trunk/mhdf/include/mhdf.h 2008-02-05 20:11:04 UTC (rev 1587)
+++ MOAB/trunk/mhdf/include/mhdf.h 2008-02-06 01:00:42 UTC (rev 1588)
@@ -1553,10 +1553,41 @@
enum mhdf_TagDataType tag_type,
int size,
int storage,
- void* default_value,
- void* global_value,
+ const void* default_value,
+ const void* global_value,
hid_t hdf_type,
mhdf_Status* status );
+
+/** \brief Add variable-length tag to file
+ *
+ * Add a new tag to the file. This function must be called
+ * to define the tag characteristics before values for the
+ * tag can be written. Use this function if the tag values
+ * are not fixed-length.
+ *
+ *\param file_handle The file
+ *\param tag_name The tag name
+ *\param tag_type The tag type.
+ *\param storage MOAB storage type (dense, sparse, etc.)
+ *\param default_value Default value for tag, or NULL if none.
+ *\param default_value_length Length of default value.
+ *\param global_value Global value for tag, or NULL if none.
+ *\param global_value_length Length of global value.
+ *\param hdf_type If non-zero, assumed to be a user-specified type
+ * for opaque data. Ignored if tag_type is not
+ * mhdf_OPAQUE.
+ */
+void
+mhdf_createVarLenTag( mhdf_FileHandle file_handle,
+ const char* tag_name,
+ enum mhdf_TagDataType tag_type,
+ int storage,
+ const void* default_value,
+ int default_value_length,
+ const void* global_value,
+ int global_value_length,
+ hid_t hdf_type,
+ mhdf_Status* status );
/** \brief Get the number of tags in the file.
@@ -1594,10 +1625,12 @@
*\param size_out Depends on value of class_out:
* - mhdf_OPAQUE - size of opaque data in bytes
* - mhdf_BITFIELD - number of bits
- * - for everything else, if the tag data is an
- * array, the length of the array. 1 otherwise.
+ * - if data is fixed-length array, length of array
+ * - if data is single value, 1
+ * - if data is a variable-length array, -1
*\param tstt_storage_out The value of the TSTT enum for storage (dense, sparse, etc.)
- *\param have_default_out Non-zero if file contains a default value for the tag.
+ *\param have_default_out Non-zero if file contains a default value for the tag.
+ * Length of default value if variable-lenth tag.
*\param have_global_out Non-zero if the file contains a global/mesh value for the tag.
*\param have_sparse_out Non-zero if the file contains a sparse data table for this tag.
*/
@@ -1751,9 +1784,9 @@
*\param file_handle The file.
*\param tag_name The tag.
*\param num_values The number of tag values to be written.
- *\param entities_and_values_out The handles to the pair of file objects.
+ *\param entities_and_values_out The handles to the file objects.
* The first is the vector of global IDs. The second
- * is the list of corresponding tag values.
+ * is the list of corresponding tag values.
*\param status Passed back status of API call.
*/
void
@@ -1763,6 +1796,33 @@
hid_t entities_and_values_out[2],
mhdf_Status* status );
+/** \brief Create file objects to store (sparse) variable-length tag data
+ *
+ * Create the file objects to store all sparse data for a given tag in. The
+ * sparse data is stored in a pair of objects. The first is a vector of
+ * global IDs. The second is a vector of tag values for each entity specified
+ * in the list of global IDs.
+ *
+ *\param file_handle The file.
+ *\param tag_name The tag.
+ *\param num_entities The number of entities for which tag values are to be stored
+ *\param num_values The total number of scalar values to be written (the
+ * total number of bytes of data for all tags for opaque
+ * data.)
+ *\param entities_and_values_out The handles to the file objects.
+ * The first is the vector of global IDs. The second
+ * is the list of corresponding tag values. The third
+ * is the handle to the index table.
+ *\param status Passed back status of API call.
+ */
+void
+mhdf_createVarLenTagData( mhdf_FileHandle file_handle,
+ const char* tag_name,
+ long num_entities,
+ long num_values,
+ hid_t entities_and_values_out[3],
+ mhdf_Status* status );
+
/** \brief Create file objects to read sparse tag data
*
* Open the file objects containing all sparse data for a given tag in. The
@@ -1772,17 +1832,20 @@
*
*\param file_handle The file.
*\param tag_name The tag.
- *\param num_values_out The number of tag values.
+ *\param num_values_out The number of entities for which tag values are stored.
*\param entities_and_values_out The handles to the pair of file objects.
* The first is the vector of global IDs. The second
- * is the list of corresponding tag values.
+ * is the list of corresponding tag values. The third
+ * is the handle to the index table, iff the tag is
+ * variable-length. If the tag is fixed-length, this
+ * value is not set.
*\param status Passed back status of API call.
*/
void
mhdf_openSparseTagData( mhdf_FileHandle file_handle,
const char* tag_name,
long* num_values_out,
- hid_t entities_and_values_out[2],
+ hid_t entities_and_values_out[3],
mhdf_Status* status );
/** \brief Write Global ID list for sparse tag data
@@ -1807,6 +1870,8 @@
const void* id_list,
mhdf_Status* status );
+
+
/** \brief Write tag value list for sparse tag data
*
*\param value_handle The second handle passed back from either
@@ -1830,6 +1895,28 @@
const void* tag_data,
mhdf_Status* status );
+/**\brief Write sparse tag end indices for variable-length tag data
+ *
+ * Write sparse tag end indices for variable-length tag data.
+ * Each value in the list is the *last* index (zero-based) into the tag
+ * data for the corresponding entity.
+ *
+ *\param tag_handle handle to the data object to write to.
+ *\param offset The offset into the table at which to begin writting
+ *\param count The number of values to write.
+ *\param hdf_integer_type The type of the values pointed to by end_indices
+ * (must be an integer type).
+ *\param end_indices The values to store in the table.
+ *\param status Output: API result.
+ */
+void
+mhdf_writeSparseTagIndices( hid_t tag_handle,
+ long offset,
+ long count,
+ hid_t hdf_integer_type,
+ const void* end_indices,
+ mhdf_Status* status );
+
/** \brief Read Global ID list for sparse tag data
*
*\param id_handle The first handle passed back from either
@@ -1859,22 +1946,44 @@
* \ref mhdf_openSparseTagData.
*\param offset The offset at which to begin reading.
*\param count The number of tag values to read.
- *\param hdf_integer_type The type of the data in memory. If this is specified,
+ *\param hdf_type The type of the data in memory. If this is specified,
* it must be possible for the HDF library to convert
* between this type and the type the tag data is stored
* as. If zero, the values will be read as opaque data.
- *\param id_list Memory location at which to store tag values.
+ *\param memory Memory location at which to store tag values.
*\param status Passed back status of API call.
*/
void
mhdf_readSparseTagValues( hid_t value_handle,
long offset,
long count,
- hid_t hdf_integer_type,
- void* id_list,
+ hid_t hdf_type,
+ void* memory,
mhdf_Status* status );
+/**\brief Read sparse tag end indices for variable-length tag data
+ *
+ * Read sparse tag end indices for variable-length tag data.
+ * Each value in the list is the *last* index (zero-based) into the tag
+ * data for the corresponding entity.
+ *
+ *\param tag_handle handle to the data object to read from.
+ *\param offset The offset into the table at which to begin reading
+ *\param count The number of values to read.
+ *\param hdf_integer_type The type of the values pointed to by end_indices
+ * (must be an integer type).
+ *\param end_indices Memory in which to store the data read from the table.
+ *\param status Output: API result.
+ */
+void
+mhdf_readSparseTagIndices( hid_t tag_handle,
+ long offset,
+ long count,
+ hid_t hdf_integer_type,
+ void* end_indices,
+ mhdf_Status* status );
+
/*@}*/
Modified: MOAB/trunk/mhdf/src/names-and-paths.h
===================================================================
--- MOAB/trunk/mhdf/src/names-and-paths.h 2008-02-05 20:11:04 UTC (rev 1587)
+++ MOAB/trunk/mhdf/src/names-and-paths.h 2008-02-06 01:00:42 UTC (rev 1588)
@@ -32,6 +32,7 @@
#define SPARSE_ENTITY_NAME "id_list"
#define SPARSE_VALUES_NAME "values"
#define TAG_TYPE_NAME "type"
+#define TAG_VAR_INDICES "var_indices"
/* Common names for data node/element/set groups */
#define DENSE_TAG_SUBGROUP TAG_GROUP_NAME "/"
@@ -69,6 +70,7 @@
#define TAG_GLOBAL_ATTRIB "global"
#define TAG_TYPE_ATTRIB "class"
#define TAG_HANDLE_TYPE_ATTRIB "is_handle"
+#define TAG_VARLEN_ATTRIB "variable_length"
#define ELEM_TYPE_ATTRIB "element_type"
#define START_ID_ATTRIB "start_id"
#define MAX_ID_ATTRIB "max_id"
Modified: MOAB/trunk/mhdf/src/tags.c
===================================================================
--- MOAB/trunk/mhdf/src/tags.c 2008-02-05 20:11:04 UTC (rev 1587)
+++ MOAB/trunk/mhdf/src/tags.c 2008-02-06 01:00:42 UTC (rev 1588)
@@ -171,37 +171,75 @@
return type_id;
}
+/** Helper function to write default and mesh values for tag
+ *\param tag_id The file object upon which to attach the attribute
+ *\param attrib_name The name of the attribute object
+ *\param type_id The data type of the attribute data
+ *\param value Pointer to attribute data
+ *\param value_size Size of attribute data, as multiple of type indicated
+ * by type_id. Should be 1 except for variable-length tag data.
+ */
+static
+int store_tag_val_in_attrib( hid_t tag_id,
+ const char* attrib_name,
+ hid_t type_id,
+ const void* value,
+ hsize_t value_size,
+ mhdf_Status* status )
+{
+ hid_t write_type;
+ int rval;
+ if (value_size == 1)
+ write_type = type_id;
+ else if (H5Tget_class(type_id) == H5T_OPAQUE)
+ write_type = H5Tcreate( H5T_OPAQUE, abs(value_size) );
+ else
+ write_type = H5Tarray_create( type_id, 1, &value_size, 0 );
+
+ if (write_type < 0) {
+ mhdf_setFail( status, "Error constructing type object for tag mesh/default value" );
+ return -1;
+ }
+
+ rval = mhdf_create_scalar_attrib( tag_id, attrib_name, write_type, value, status );
+ if (write_type != type_id)
+ H5Tclose( write_type );
+
+ return rval;
+}
-
-void
-mhdf_createTag( mhdf_FileHandle file_handle,
- const char* tag_name,
- enum mhdf_TagDataType tag_type,
- int size,
- int storage,
- void* default_value,
- void* global_value,
- hid_t hdf_type,
- mhdf_Status* status )
+static
+hid_t create_tag_common( mhdf_FileHandle file_handle,
+ const char* tag_name,
+ enum mhdf_TagDataType tag_type,
+ int size,
+ int storage,
+ const void* default_value,
+ int default_value_size_in,
+ const void* global_value,
+ int global_value_size_in,
+ hid_t hdf_type,
+ mhdf_Status* status )
{
hid_t temp_id, group_id, tag_id;
char* path;
FileHandle* file_ptr;
herr_t rval;
hsize_t arr_len;
- int one = 1;
- API_BEGIN;
+ int one = 1, var_len=0;
+ hsize_t default_value_size = default_value_size_in;
+ hsize_t global_value_size = global_value_size_in;
/* Validate input */
file_ptr = (FileHandle*)file_handle;
if (!mhdf_check_valid_file( file_ptr, status ))
- return ;
+ return -1;
if (!tag_name || !*tag_name)
{
mhdf_setFail( status, "Invalid tag name" );
- return ;
+ return -1;
}
@@ -211,7 +249,7 @@
if (group_id < 0)
{
mhdf_setFail( status, "H5Gopen(\"%s\") failed.", TAG_GROUP );
- return;
+ return -1;
}
/* Create path string for tag object */
@@ -220,7 +258,7 @@
if (!path)
{
H5Gclose( group_id );
- return;
+ return -1;
}
/* Create group for this tag */
@@ -231,7 +269,7 @@
mhdf_setFail( status, "H5Gcreate( \"%s\" ) failed.", path );
free( path );
H5Gclose( group_id );
- return;
+ return -1;
}
/* Store the tag name as the comment on the group entry */
@@ -243,7 +281,7 @@
{
mhdf_setFail( status, "H5Gset_comment failed for tag \"%s\"", tag_name );
H5Gclose( tag_id );
- return;
+ return -1;
}
/* Store TSTT tag type as attribute */
@@ -256,7 +294,7 @@
if (!rval)
{
H5Gclose( tag_id );
- return;
+ return -1;
}
if (hdf_type)
@@ -270,14 +308,19 @@
{
default:
case mhdf_OPAQUE:
- hdf_type = H5Tcreate( H5T_OPAQUE, size );
+ arr_len = 1;
+ hdf_type = H5Tcreate( H5T_OPAQUE, abs(size) );
H5Tset_tag( hdf_type, "tag_data" );
- arr_len = 1;
break;
case mhdf_BITFIELD:
arr_len = 1;
- if (size <= 8)
+ if (size <= 0)
+ {
+ mhdf_setFail( status, "Invalid size (%d) for bit tag.", (int)size );
+ return -1;
+ }
+ else if (size <= 8)
hdf_type = H5Tcopy( H5T_NATIVE_B8 );
else if (size <= 16)
hdf_type = H5Tcopy( H5T_NATIVE_B16 );
@@ -287,34 +330,34 @@
hdf_type = H5Tcopy( H5T_NATIVE_B64 );
else
{
- mhdf_setFail( status, "Cannot createa a bit tag larger than 64-bits. %d bits requested.\n", (int)size);
- return;
+ mhdf_setFail( status, "Cannot create a bit tag larger than 64-bits. %d bits requested.\n", (int)size);
+ return -1;
}
if (0 > H5Tset_precision( hdf_type, size ))
{
mhdf_setFail( status, "H5Tset_precision failed.");
- return;
+ return -1;
}
break;
case mhdf_ENTITY_ID:
- arr_len = size;
+ arr_len = abs(size);
hdf_type = H5Tcopy( H5T_NATIVE_INT );
break;
case mhdf_BOOLEAN:
- arr_len = size;
+ arr_len = abs(size);
hdf_type = H5Tcopy( H5T_NATIVE_UCHAR );
break;
case mhdf_INTEGER:
- arr_len = size;
+ arr_len = abs(size);
hdf_type = H5Tcopy( H5T_NATIVE_INT );
break;
case mhdf_FLOAT:
- arr_len = size;
+ arr_len = abs(size);
hdf_type = H5Tcopy( H5T_NATIVE_DOUBLE );
break;
}
@@ -324,18 +367,33 @@
{
mhdf_setFail( status, "Failed to create tag type object." );
H5Gclose( tag_id );
- return;
+ return -1;
}
- if (arr_len > 1)
+ if (size < -1 || !arr_len)
{
+ mhdf_setFail( status, "Invalid 'size' parameter passed to mhdf_createTag (%d)", (int)size);
+ H5Gclose( tag_id );
+ return -1;
+ }
+ else if (size == -1)
+ {
+ /* Note: we don't do anything with this here. We rely on
+ * the app to ask us to create the index table later.
+ */
+ arr_len = 1;
+ /* need to know this later, when storing default/global values */
+ var_len = 1;
+ }
+ else if (arr_len > 1)
+ {
temp_id = H5Tarray_create( hdf_type, 1, &arr_len, NULL );
H5Tclose( hdf_type );
if (temp_id < 0)
{
mhdf_setFail( status, "Failed to create tag type object." );
H5Gclose( tag_id );
- return;
+ return -1;
}
hdf_type = temp_id;
}
@@ -351,7 +409,7 @@
mhdf_setFail( status, "H5Tcommit failed for tag \"%s\"", tag_name );
H5Tclose( hdf_type );
H5Gclose( tag_id );
- return;
+ return -1;
}
/* If tag is entity handle, make note of it */
@@ -366,7 +424,7 @@
{
H5Gclose( tag_id );
H5Tclose( hdf_type );
- return;
+ return -1;
}
}
@@ -376,43 +434,86 @@
if (default_value)
{
- rval = mhdf_create_scalar_attrib( tag_id,
- TAG_DEFAULT_ATTRIB,
- hdf_type,
- default_value,
- status);
- if (!rval)
- {
+ rval = store_tag_val_in_attrib( tag_id, TAG_DEFAULT_ATTRIB, hdf_type, default_value,
+ var_len ? default_value_size : 1, status );
+ if (!rval) {
H5Gclose( tag_id );
H5Tclose( hdf_type );
- return;
+ return -1;
}
}
-
/* Store global tag value as attribute */
if (global_value)
{
- rval = mhdf_create_scalar_attrib( tag_id,
- TAG_GLOBAL_ATTRIB,
- hdf_type,
- global_value,
- status );
- if (!rval)
- {
+ rval = store_tag_val_in_attrib( tag_id, TAG_GLOBAL_ATTRIB, hdf_type, global_value,
+ var_len ? global_value_size : 1, status );
+ if (!rval) {
H5Gclose( tag_id );
H5Tclose( hdf_type );
- return;
+ return -1;
}
}
- H5Gclose( tag_id );
H5Tclose( hdf_type );
mhdf_setOkay( status );
+ return tag_id;
+}
+
+
+void
+mhdf_createTag( mhdf_FileHandle file_handle,
+ const char* tag_name,
+ enum mhdf_TagDataType tag_type,
+ int size,
+ int storage,
+ const void* default_value,
+ const void* global_value,
+ hid_t hdf_type,
+ mhdf_Status* status )
+{
+ hid_t tag_id;
+ API_BEGIN;
+ tag_id = create_tag_common( file_handle, tag_name, tag_type, size, storage,
+ default_value, 1, global_value, 1, hdf_type, status );
+ if (tag_id >= 0)
+ H5Gclose( tag_id );
API_END;
}
+void
+mhdf_createVarLenTag( mhdf_FileHandle file_handle,
+ const char* tag_name,
+ enum mhdf_TagDataType tag_type,
+ int storage,
+ const void* default_value,
+ int default_value_length,
+ const void* global_value,
+ int global_value_length,
+ hid_t hdf_type,
+ mhdf_Status* status )
+{
+ herr_t rval;
+ hid_t tag_id;
+ int one = 1;
+
+ API_BEGIN;
+ tag_id = create_tag_common( file_handle, tag_name, tag_type, -1, storage,
+ default_value, default_value_length,
+ global_value, global_value_length,
+ hdf_type, status );
+ if (tag_id >= 0) {
+ rval = mhdf_create_scalar_attrib( tag_id,
+ TAG_VARLEN_ATTRIB,
+ H5T_NATIVE_INT,
+ &one,
+ status );
+ H5Gclose( tag_id );
+ }
+ API_END;
+}
+
int
mhdf_getNumberTags( mhdf_FileHandle file_handle, mhdf_Status* status )
{
@@ -538,8 +639,68 @@
API_END;
return result;
}
+
+static int get_attrib_array_length_handle( hid_t attrib_id )
+{
+ hid_t type_id;
+ int rank;
+ hsize_t dims[H5S_MAX_RANK];
+ int perm[H5S_MAX_RANK];
+ type_id = H5Aget_type( attrib_id );
+ switch (H5Tget_class(type_id)) {
+ case H5T_NO_CLASS:
+ dims[0] = -1;
+ break;
+ case H5T_OPAQUE:
+ dims[0] = H5Tget_size( type_id );
+ break;
+ case H5T_ARRAY:
+ rank = H5Tget_array_dims( type_id, dims, perm );
+ if (rank == 1)
+ break;
+ else
+ return -1;
+ default:
+ dims[0] = 1;
+ break;
+ }
+
+ H5Tclose( type_id );
+ return dims[0];
+}
+
+
+/*
+static int get_attrib_array_length_index( hid_t object_id, unsigned int index )
+{
+ hid_t attrib_id;
+ int result;
+
+ attrib_id = H5Aopen_idx( object_id, index );
+ if (attrib_id < 0)
+ return -1;
+
+ result = get_attrib_array_length_handle( attrib_id );
+ H5Aclose( attrib_id );
+ return result;
+}
+*/
+static int get_attrib_array_length_name( hid_t file, const char* path )
+{
+ hid_t attrib_id;
+ int result;
+
+ attrib_id = H5Aopen_name( file, path );
+ if (attrib_id < 0)
+ return -1;
+
+ result = get_attrib_array_length_handle( attrib_id );
+ H5Aclose( attrib_id );
+ return result;
+}
+
void
mhdf_getTagInfo( mhdf_FileHandle file_handle,
@@ -556,7 +717,7 @@
int i, rval, is_handle;
hsize_t size, sup_size;
unsigned int index;
- int rank;
+ int rank, var_data;
hsize_t dims[H5S_MAX_RANK];
int perm[H5S_MAX_RANK];
H5T_class_t class_tmp;
@@ -590,6 +751,15 @@
return;
}
*have_sparse_out = rval ? 1 : 0;
+
+ /* Check for variable-length tag data */
+ rval = mhdf_find_attribute( tag_id, TAG_VARLEN_ATTRIB, &index, status );
+ if (rval < 0)
+ {
+ H5Gclose( tag_id );
+ return;
+ }
+ var_data = rval ? 1 : 0;
/* Check if have default value for tag */
rval = mhdf_find_attribute( tag_id, TAG_DEFAULT_ATTRIB, &index, status );
@@ -598,7 +768,19 @@
H5Gclose( tag_id );
return;
}
- *have_default_out = rval ? 1 : 0;
+ if (!rval)
+ *have_default_out = 0;
+ else if (!var_data)
+ *have_default_out = 1;
+ else {
+ /* *have_default_out = get_attrib_array_length_index( tag_id, index ); */
+ *have_default_out = get_attrib_array_length_name( tag_id, TAG_DEFAULT_ATTRIB );
+ if (*have_default_out < 0) {
+ mhdf_setFail( status, "Error checking length of default value for tag: %s\n", tag_name );
+ H5Gclose( tag_id );
+ return;
+ }
+ }
/* Check if have global value for tag */
rval = mhdf_find_attribute( tag_id, TAG_GLOBAL_ATTRIB, &index, status );
@@ -607,7 +789,19 @@
H5Gclose( tag_id );
return;
}
- *have_global_out = rval ? 1 : 0;
+ if (!rval)
+ *have_global_out = 0;
+ else if (!var_data)
+ *have_global_out = 1;
+ else {
+ /* *have_global_out = get_attrib_array_length_index( tag_id, index ); */
+ *have_global_out = get_attrib_array_length_name( tag_id, TAG_GLOBAL_ATTRIB );
+ if (*have_global_out < 0) {
+ mhdf_setFail( status, "Error checking length of global value for tag: %s\n", tag_name );
+ H5Gclose( tag_id );
+ return;
+ }
+ }
/* Get TSTT tag class */
rval = mhdf_read_scalar_attrib( tag_id, TAG_TYPE_ATTRIB,
@@ -762,10 +956,74 @@
}
*class_out = mhdf_ENTITY_ID;
}
+
+ if (var_data)
+ {
+ if (*size_out != 1 || *class_out == mhdf_BITFIELD)
+ {
+ mhdf_setFail( status, "Invalid or unexpected variable-length tag data" );
+ return;
+ }
+ *size_out = -1;
+ }
mhdf_setOkay( status );
API_END;
}
+
+
+static int
+read_tag_attrib_data( hid_t tag_id,
+ const char* attrib_name,
+ hid_t type_id,
+ const void* data,
+ int is_var_len,
+ mhdf_Status* status )
+{
+ int rval, index;
+ hid_t read_type = type_id;
+ hsize_t len;
+
+ /* Check if tag has attribute */
+ rval = mhdf_find_attribute( tag_id, attrib_name, &index, status );
+ if (rval < 0)
+ return 0;
+ else if (0 == rval)
+ return 1;
+
+ if (NULL == data)
+ {
+ mhdf_setFail( status, "Invalid input." );
+ return;
+ }
+
+ if (is_var_len)
+ {
+ /* len = get_attrib_array_length_index(tag_id, index); */
+ len = get_attrib_array_length_name(tag_id, attrib_name);
+ if (len < 0)
+ {
+ mhdf_setFail( status, "Failed to read length of default/mesh value for tag" );
+ return 0;
+ }
+ /* caller passes type_id == 0 for OPAQUE */
+ if (0 == type_id)
+ read_type = H5Tcreate( H5T_OPAQUE, len );
+ else
+ read_type = H5Tarray_create( type_id, 1, &len, 0 );
+ if (read_type < 0)
+ {
+ mhdf_setFail( status, "Failed to read mesh/default value for tag" );
+ return;
+ }
+ }
+
+ rval = mhdf_read_scalar_attrib( tag_id, attrib_name, read_type, data, status );
+ if (is_var_len)
+ H5Tclose( read_type );
+
+ return rval;
+}
void
mhdf_getTagValues( mhdf_FileHandle file_handle,
@@ -775,9 +1033,10 @@
void* global_value,
mhdf_Status* status )
{
- hid_t tag_id;
- int rval;
- unsigned int junk;
+ hid_t tag_id, temp_id;
+ int rval, var_data;
+ hsize_t len;
+ unsigned int index;
API_BEGIN;
/* check args */
@@ -791,61 +1050,34 @@
tag_id = get_tag( file_handle, tag_name, status );
if (tag_id < 0)
return;
-
- /* Check if tag has default value */
- rval = mhdf_find_attribute( tag_id, TAG_DEFAULT_ATTRIB, &junk, status );
+
+ /* Check for variable-length tag data */
+ rval = mhdf_find_attribute( tag_id, TAG_VARLEN_ATTRIB, &index, status );
if (rval < 0)
{
H5Gclose( tag_id );
return;
}
-
- /* Get default if there is one */
- if (rval)
+ var_data = rval ? 1 : 0;
+
+ /* Read default value if present */
+ rval = read_tag_attrib_data( tag_id, TAG_DEFAULT_ATTRIB, output_data_type,
+ default_value, var_data, status );
+ if (!rval)
{
- if (NULL == default_value)
- {
- mhdf_setFail( status, "Invalid input." );
- return;
- }
-
- rval = mhdf_read_scalar_attrib( tag_id, TAG_DEFAULT_ATTRIB,
- output_data_type, default_value,
- status );
- if (!rval)
- {
- H5Gclose( tag_id );
- return;
- }
+ H5Gclose( tag_id );
+ return;
}
- /* Check if tag has global value */
- rval = mhdf_find_attribute( tag_id, TAG_GLOBAL_ATTRIB, &junk, status );
- if (rval < 0)
+ /* Read mesh value if present */
+ rval = read_tag_attrib_data( tag_id, TAG_GLOBAL_ATTRIB, output_data_type,
+ global_value, var_data, status );
+ if (!rval)
{
H5Gclose( tag_id );
return;
}
- /* Get global value if there is one */
- if (rval)
- {
- if (NULL == global_value)
- {
- mhdf_setFail( status, "Invalid input." );
- return;
- }
-
- rval = mhdf_read_scalar_attrib( tag_id, TAG_GLOBAL_ATTRIB,
- output_data_type, global_value,
- status );
- if (!rval)
- {
- H5Gclose( tag_id );
- return;
- }
- }
-
H5Gclose( tag_id );
mhdf_setOkay( status );
API_END;
@@ -1152,16 +1384,80 @@
API_END_H(2);
}
+void
+mhdf_createVarLenTagData( mhdf_FileHandle file_handle,
+ const char* tag_name,
+ long num_entities,
+ long num_values,
+ hid_t handles_out[3],
+ mhdf_Status* status )
+{
+ hid_t tag_id, index_id, data_id, type_id, offset_id;
+ hsize_t count = (hsize_t)num_entities;
+ API_BEGIN;
+
+ tag_id = get_tag( file_handle, tag_name, status );
+ if (tag_id < 0) return ;
+
+ type_id = H5Topen( tag_id, TAG_TYPE_NAME );
+ if (type_id < 0)
+ {
+ H5Gclose( tag_id );
+ mhdf_setFail( status, "Failed to get type object for tag \"%s\".", tag_name );
+ return ;
+ }
+
+ index_id = mhdf_create_table( tag_id, SPARSE_ENTITY_NAME,
+ H5T_NATIVE_LONG, 1, &count,
+ status );
+ if (index_id < 0)
+ {
+ H5Gclose( tag_id );
+ H5Tclose( type_id );
+ return ;
+ }
+
+ offset_id = mhdf_create_table( tag_id, TAG_VAR_INDICES,
+ H5T_NATIVE_LONG, 1, &count,
+ status );
+ if (index_id < 0)
+ {
+ H5Dclose( offset_id );
+ H5Gclose( tag_id );
+ H5Tclose( type_id );
+ return ;
+ }
+
+ count = (hsize_t)num_values;
+ data_id = mhdf_create_table( tag_id, SPARSE_VALUES_NAME,
+ type_id, 1, &count, status );
+ H5Tclose( type_id );
+ H5Gclose( tag_id );
+ if (data_id < 0)
+ {
+ H5Dclose( offset_id );
+ H5Dclose( index_id );
+ return ;
+ }
+
+ handles_out[0] = index_id;
+ handles_out[1] = data_id;
+ handles_out[2] = offset_id;
+ mhdf_setOkay( status );
+ API_END_H(3);
+}
+
void
mhdf_openSparseTagData( mhdf_FileHandle file_handle,
const char* tag_name,
long* num_values_out,
- hid_t handles_out[2],
+ hid_t handles_out[3],
mhdf_Status* status )
{
- hid_t tag_id, index_id, data_id;
+ hid_t tag_id, index_id, data_id, offset_id = -1;
hsize_t size1, size2;
+ int rval, idx;
API_BEGIN;
tag_id = get_tag( file_handle, tag_name, status );
@@ -1175,16 +1471,42 @@
}
data_id = mhdf_open_table( tag_id, SPARSE_VALUES_NAME, 1, &size2, status );
- H5Gclose( tag_id );
if (data_id < 0)
{
+ H5Gclose( tag_id );
H5Dclose( index_id );
return ;
}
+ /* check if tag is variable-lentgth */
+ rval = mhdf_find_attribute( tag_id, TAG_VARLEN_ATTRIB, &idx, status );
+ if (rval < 0) {
+ H5Gclose( tag_id );
+ H5Dclose( index_id );
+ H5Dclose( data_id );
+ return ;
+ }
+
+ /* If variable length...
+ * Replace if data table (size2) with size of offset table. For variable-length
+ * tags, the index and offset tables should be the same size, but the size of
+ * the data table could be anything. */
+ if (rval) {
+ offset_id = mhdf_open_table( tag_id, TAG_VAR_INDICES, 1, &size2, status );
+ if (offset_id < 0) {
+ H5Gclose( tag_id );
+ H5Dclose( index_id );
+ H5Dclose( data_id );
+ return ;
+ }
+ }
+
+ H5Gclose( tag_id );
if (size1 != size2)
{
mhdf_setFail( status, "Data length mismatch for sparse tag data -- invalid file.");
+ if (offset_id >= 0)
+ H5Dclose( offset_id );
H5Dclose( index_id );
H5Dclose( data_id );
return ;
@@ -1193,6 +1515,8 @@
handles_out[0] = index_id;
handles_out[1] = data_id;
+ if (offset_id >= 0)
+ handles_out[2] = offset_id;
mhdf_setOkay( status );
API_END_H(2);
}
@@ -1243,6 +1567,19 @@
}
void
+mhdf_writeSparseTagIndices( hid_t table_id,
+ long offset,
+ long count,
+ hid_t int_type,
+ const void* indices,
+ mhdf_Status* status )
+{
+ API_BEGIN;
+ mhdf_write_data( table_id, offset, count, int_type, indices, status );
+ API_END;
+}
+
+void
mhdf_readSparseTagEntities( hid_t table_id,
long offset,
long count,
@@ -1286,3 +1623,16 @@
H5Tclose( type_id );
API_END;
}
+
+void
+mhdf_readSparseTagIndices( hid_t table_id,
+ long offset,
+ long count,
+ hid_t int_type,
+ void* indices,
+ mhdf_Status* status )
+{
+ API_BEGIN;
+ mhdf_read_data( table_id, offset, count, int_type, indices, status );
+ API_END;
+}
More information about the moab-dev
mailing list