![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
00001 /**
00002 * MOAB, a Mesh-Oriented datABase, is a software component for creating,
00003 * storing and accessing finite element mesh data.
00004 *
00005 * Copyright 2004 Sandia Corporation. Under the terms of Contract
00006 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
00007 * retains certain rights in this software.
00008 *
00009 * This library is free software; you can redistribute it and/or
00010 * modify it under the terms of the GNU Lesser General Public
00011 * License as published by the Free Software Foundation; either
00012 * version 2.1 of the License, or (at your option) any later version.
00013 *
00014 */
00015
00016 #include
00017 #include
00018 #include
00019 #include
00020 #include
00021 #include /* for H5S_MAX_RANK */
00022 #include
00023 #include
00024 #include "status.h"
00025 #include "file-handle.h"
00026 #include "mhdf.h"
00027 #include "util.h"
00028 #include "names-and-paths.h"
00029
00030 hid_t mhdf_getNativeType( hid_t input_type, int size, mhdf_Status* status )
00031 {
00032 H5T_sign_t sgn;
00033 H5T_class_t cls;
00034 hid_t tmp_id, type_id;
00035
00036 mhdf_setOkay( status );
00037
00038 cls = H5Tget_class( input_type );
00039 switch( cls )
00040 {
00041 case H5T_FLOAT:
00042 switch( size )
00043 {
00044 case 4:
00045 return H5T_NATIVE_FLOAT;
00046 case 8:
00047 return H5T_NATIVE_DOUBLE;
00048 case 16:
00049 return H5T_NATIVE_LDOUBLE;
00050 default:
00051 mhdf_setFail( status, "Invalid size for floating point type: %d", size );
00052 return -1;
00053 }
00054
00055 case H5T_INTEGER:
00056 sgn = H5Tget_sign( input_type );
00057 if( H5T_SGN_ERROR == sgn )
00058 {
00059 mhdf_setFail( status, "Internall errror calling H5Tget_sign." );
00060 return -1;
00061 }
00062 if( sizeof( char ) == size )
00063 return sgn == H5T_SGN_NONE ? H5T_NATIVE_UCHAR : H5T_NATIVE_SCHAR;
00064 else if( sizeof( short ) == size )
00065 return sgn == H5T_SGN_NONE ? H5T_NATIVE_USHORT : H5T_NATIVE_SHORT;
00066 else if( sizeof( int ) == size )
00067 return sgn == H5T_SGN_NONE ? H5T_NATIVE_UINT : H5T_NATIVE_INT;
00068 else if( sizeof( long ) == size )
00069 return sgn == H5T_SGN_NONE ? H5T_NATIVE_ULONG : H5T_NATIVE_LONG;
00070 else if( (int)H5Tget_size( H5T_NATIVE_LLONG ) == size )
00071 return sgn == H5T_SGN_NONE ? H5T_NATIVE_ULLONG : H5T_NATIVE_LLONG;
00072
00073 mhdf_setFail( status, "Invalid size for integer type: %d", size );
00074 return -1;
00075
00076 case H5T_ENUM:
00077 tmp_id = H5Tget_super( input_type );
00078 if( tmp_id < 0 )
00079 {
00080 mhdf_setFail( status, "Internal error calling H5Tget_super." );
00081 return -1;
00082 }
00083 type_id = mhdf_getNativeType( tmp_id, size, status );
00084 H5Tclose( tmp_id );
00085 return type_id;
00086
00087 case H5T_TIME:
00088 case H5T_OPAQUE:
00089 case H5T_REFERENCE:
00090 mhdf_setFail( status, "Unsupported type class." );
00091 return -1;
00092
00093 case H5T_COMPOUND:
00094 case H5T_VLEN:
00095 case H5T_ARRAY:
00096 case H5T_STRING:
00097 mhdf_setFail( status, "Only atomic types are supported." );
00098 return -1;
00099
00100 default:
00101 mhdf_setFail( status, "Internal error calling H5Tget_class. Bad handle?" );
00102 return -1;
00103 }
00104 }
00105
00106 static hid_t get_tag( mhdf_FileHandle file_handle, const char* tag_name, hid_t* id_type, mhdf_Status* status )
00107 {
00108 hid_t group_id, tag_id;
00109 char* path;
00110 FileHandle* file_ptr;
00111
00112 file_ptr = (FileHandle*)file_handle;
00113 if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
00114
00115 if( NULL != id_type ) *id_type = file_ptr->id_type;
00116
00117 path = mhdf_name_to_path_copy( tag_name, status );
00118 if( NULL == path ) return -1;
00119
00120 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
00121 group_id = H5Gopen2( file_ptr->hdf_handle, TAG_GROUP, H5P_DEFAULT );
00122 #else
00123 group_id = H5Gopen( file_ptr->hdf_handle, TAG_GROUP );
00124 #endif
00125 if( group_id < 0 )
00126 {
00127 mhdf_setFail( status, "Failed to open tag group." );
00128 free( path );
00129 return -1;
00130 }
00131
00132 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
00133 tag_id = H5Gopen2( group_id, path, H5P_DEFAULT );
00134 #else
00135 tag_id = H5Gopen( group_id, path );
00136 #endif
00137 H5Gclose( group_id );
00138 free( path );
00139 if( tag_id < 0 )
00140 {
00141 mhdf_setFail( status, "Failed to open tag data for tag \"%s\".", tag_name );
00142 return -1;
00143 }
00144
00145 mhdf_setOkay( status );
00146 return tag_id;
00147 }
00148
00149 static hid_t get_tag_type( FileHandle* file_ptr, const char* tag_path, mhdf_Status* status )
00150 {
00151 hid_t group_id, tag_id, type_id;
00152
00153 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
00154 group_id = H5Gopen2( file_ptr->hdf_handle, TAG_GROUP, H5P_DEFAULT );
00155 #else
00156 group_id = H5Gopen( file_ptr->hdf_handle, TAG_GROUP );
00157 #endif
00158 if( group_id < 0 )
00159 {
00160 mhdf_setFail( status, "Failed to open tag group." );
00161 return -1;
00162 }
00163
00164 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
00165 tag_id = H5Gopen2( group_id, tag_path, H5P_DEFAULT );
00166 #else
00167 tag_id = H5Gopen( group_id, tag_path );
00168 #endif
00169 H5Gclose( group_id );
00170 if( tag_id < 0 )
00171 {
00172 mhdf_setFail( status, "Failed to open group for tag \"%s\".", tag_path );
00173 return -1;
00174 }
00175
00176 #if defined( H5Topen_vers ) && H5Topen_vers > 1
00177 type_id = H5Topen2( tag_id, TAG_TYPE_NAME, H5P_DEFAULT );
00178 #else
00179 type_id = H5Topen( tag_id, TAG_TYPE_NAME );
00180 #endif
00181 H5Gclose( tag_id );
00182 if( type_id < 0 )
00183 {
00184 mhdf_setFail( status, "Failed to open type data for tag \"%s\".", tag_path );
00185 return -1;
00186 }
00187
00188 return type_id;
00189 }
00190
00191 /** Helper function to write default and mesh values for tag
00192 *\param tag_id The file object upon which to attach the attribute
00193 *\param attrib_name The name of the attribute object
00194 *\param type_id The data type of the attribute data
00195 *\param value Pointer to attribute data
00196 *\param value_size Size of attribute data, as multiple of type indicated
00197 * by type_id. Should be 1 except for variable-length tag data.
00198 */
00199 static int store_tag_val_in_attrib( hid_t tag_id,
00200 const char* attrib_name,
00201 hid_t type_id,
00202 const void* value,
00203 hsize_t value_size,
00204 mhdf_Status* status )
00205 {
00206 hid_t write_type;
00207 int rval;
00208 if( value_size == 1 )
00209 write_type = type_id;
00210 else if( H5Tget_class( type_id ) == H5T_OPAQUE )
00211 {
00212 write_type = H5Tcreate( H5T_OPAQUE, value_size );
00213 }
00214 else
00215 {
00216 #if defined( H5Tarray_create_vers ) && H5Tarray_create_vers > 1
00217 write_type = H5Tarray_create2( type_id, 1, &value_size );
00218 #else
00219 write_type = H5Tarray_create( type_id, 1, &value_size, 0 );
00220 #endif
00221 }
00222
00223 if( write_type < 0 )
00224 {
00225 mhdf_setFail( status, "Error constructing type object for tag mesh/default value" );
00226 return -1;
00227 }
00228
00229 rval = mhdf_create_scalar_attrib( tag_id, attrib_name, write_type, value, status );
00230 if( write_type != type_id ) H5Tclose( write_type );
00231
00232 return rval;
00233 }
00234
00235 static hid_t create_tag_common( mhdf_FileHandle file_handle,
00236 const char* tag_name,
00237 enum mhdf_TagDataType tag_type,
00238 int size,
00239 int storage,
00240 const void* default_value,
00241 int default_value_size_in,
00242 const void* global_value,
00243 int global_value_size_in,
00244 hid_t hdf_type,
00245 hid_t hdf_base_type,
00246 mhdf_Status* status )
00247 {
00248 hid_t temp_id, group_id, tag_id;
00249 char* path;
00250 FileHandle* file_ptr;
00251 herr_t rval;
00252 hsize_t arr_len;
00253 int one = 1, var_len = 0;
00254 hsize_t default_value_size = default_value_size_in;
00255 hsize_t global_value_size = global_value_size_in;
00256 int close_base_type = 0;
00257
00258 /* Force standard data types over user-specified types */
00259
00260 if( tag_type != mhdf_OPAQUE ) hdf_type = 0;
00261 if( tag_type != mhdf_ENTITY_ID ) hdf_base_type = 0;
00262
00263 /* Validate input */
00264
00265 file_ptr = (FileHandle*)file_handle;
00266 if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
00267
00268 if( !tag_name || !*tag_name )
00269 {
00270 mhdf_setFail( status, "Invalid tag name" );
00271 return -1;
00272 }
00273
00274 /* Open the tag group */
00275
00276 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
00277 group_id = H5Gopen2( file_ptr->hdf_handle, TAG_GROUP, H5P_DEFAULT );
00278 #else
00279 group_id = H5Gopen( file_ptr->hdf_handle, TAG_GROUP );
00280 #endif
00281 if( group_id < 0 )
00282 {
00283 mhdf_setFail( status, "H5Gopen(\"%s\") failed.", TAG_GROUP );
00284 return -1;
00285 }
00286
00287 /* Create path string for tag object */
00288
00289 path = mhdf_name_to_path_copy( tag_name, status );
00290 if( !path )
00291 {
00292 H5Gclose( group_id );
00293 return -1;
00294 }
00295
00296 /* Create group for this tag */
00297
00298 #if defined( H5Gcreate_vers ) && H5Gcreate_vers > 1
00299 tag_id = H5Gcreate2( group_id, path, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
00300 #else
00301 tag_id = H5Gcreate( group_id, path, 3 );
00302 #endif
00303 if( tag_id < 0 )
00304 {
00305 mhdf_setFail( status, "H5Gcreate( \"%s\" ) failed.", path );
00306 free( path );
00307 H5Gclose( group_id );
00308 return -1;
00309 }
00310
00311 /* Store the tag name as the comment on the group entry */
00312
00313 rval = H5Gset_comment( group_id, path, tag_name );
00314 H5Gclose( group_id );
00315 free( path );
00316 if( rval < 0 )
00317 {
00318 mhdf_setFail( status, "H5Gset_comment failed for tag \"%s\"", tag_name );
00319 H5Gclose( tag_id );
00320 return -1;
00321 }
00322
00323 /* Store TSTT tag type as attribute */
00324
00325 rval = mhdf_create_scalar_attrib( tag_id, TAG_TYPE_ATTRIB, H5T_NATIVE_INT, &storage, status );
00326 if( !rval )
00327 {
00328 H5Gclose( tag_id );
00329 return -1;
00330 }
00331
00332 if( hdf_type )
00333 {
00334 hdf_type = H5Tcopy( hdf_type );
00335 arr_len = 1;
00336 }
00337 else
00338 {
00339 switch( tag_type )
00340 {
00341 default:
00342 case mhdf_OPAQUE:
00343 arr_len = 1;
00344 hdf_type = H5Tcreate( H5T_OPAQUE, abs( size ) );
00345 H5Tset_tag( hdf_type, "tag_data" );
00346 break;
00347
00348 case mhdf_BITFIELD:
00349 arr_len = 1;
00350 if( size <= 0 )
00351 {
00352 mhdf_setFail( status, "Invalid size (%d) for bit tag.", (int)size );
00353 return -1;
00354 }
00355 else if( size <= 8 )
00356 hdf_type = H5Tcopy( H5T_NATIVE_B8 );
00357 else if( size <= 16 )
00358 hdf_type = H5Tcopy( H5T_NATIVE_B16 );
00359 else if( size <= 32 )
00360 hdf_type = H5Tcopy( H5T_NATIVE_B32 );
00361 else if( size <= 64 )
00362 hdf_type = H5Tcopy( H5T_NATIVE_B64 );
00363 else
00364 {
00365 mhdf_setFail( status, "Cannot create a bit tag larger than 64-bits. %d bits requested.\n",
00366 (int)size );
00367 return -1;
00368 }
00369
00370 if( 0 > H5Tset_precision( hdf_type, size ) )
00371 {
00372 mhdf_setFail( status, "H5Tset_precision failed." );
00373 return -1;
00374 }
00375 break;
00376
00377 case mhdf_ENTITY_ID:
00378 arr_len = abs( size );
00379 hdf_type = H5Tcopy( H5T_NATIVE_ULONG );
00380 break;
00381
00382 case mhdf_BOOLEAN:
00383 arr_len = abs( size );
00384 hdf_type = H5Tcopy( H5T_NATIVE_UCHAR );
00385 break;
00386
00387 case mhdf_INTEGER:
00388 arr_len = abs( size );
00389 hdf_type = H5Tcopy( H5T_NATIVE_INT );
00390 break;
00391
00392 case mhdf_FLOAT:
00393 arr_len = abs( size );
00394 hdf_type = H5Tcopy( H5T_NATIVE_DOUBLE );
00395 break;
00396 }
00397 }
00398
00399 if( hdf_type <= 0 )
00400 {
00401 mhdf_setFail( status, "Failed to create tag type object." );
00402 H5Gclose( tag_id );
00403 return -1;
00404 }
00405
00406 if( hdf_base_type && H5Tget_class( hdf_type ) != H5Tget_class( hdf_base_type ) )
00407 {
00408 mhdf_setFail( status, "Invalid base type for tag default/global data" );
00409 H5Gclose( tag_id );
00410 return -1;
00411 }
00412
00413 if( size < -1 || !arr_len )
00414 {
00415 mhdf_setFail( status, "Invalid 'size' parameter passed to mhdf_createTag (%d)", (int)size );
00416 H5Gclose( tag_id );
00417 return -1;
00418 }
00419 else if( size == -1 )
00420 {
00421 /* Note: we don't do anything with this here. We rely on
00422 * the app to ask us to create the index table later.
00423 */
00424 arr_len = 1;
00425 /* need to know this later, when storing default/global values */
00426 var_len = 1;
00427 }
00428 else if( arr_len > 1 )
00429 {
00430 #if defined( H5Tarray_create_vers ) && H5Tarray_create_vers > 1
00431 temp_id = H5Tarray_create2( hdf_type, 1, &arr_len );
00432 #else
00433 temp_id = H5Tarray_create( hdf_type, 1, &arr_len, NULL );
00434 #endif
00435 H5Tclose( hdf_type );
00436 if( temp_id < 0 )
00437 {
00438 mhdf_setFail( status, "Failed to create tag type object." );
00439 H5Gclose( tag_id );
00440 return -1;
00441 }
00442 hdf_type = temp_id;
00443
00444 if( hdf_base_type )
00445 {
00446 if( H5Tequal( hdf_base_type, hdf_type ) > 0 )
00447 {
00448 hdf_base_type = hdf_type;
00449 }
00450 else
00451 {
00452 #if defined( H5Tarray_create_vers ) && H5Tarray_create_vers > 1
00453 temp_id = H5Tarray_create2( hdf_base_type, 1, &arr_len );
00454 #else
00455 temp_id = H5Tarray_create( hdf_base_type, 1, &arr_len, NULL );
00456 #endif
00457 if( temp_id < 0 )
00458 {
00459 mhdf_setFail( status, "Failed to create tag type object." );
00460 H5Gclose( tag_id );
00461 H5Tclose( hdf_type );
00462 return -1;
00463 }
00464 hdf_base_type = temp_id;
00465 close_base_type = 1;
00466 }
00467 }
00468 }
00469
00470 if( !hdf_base_type ) hdf_base_type = hdf_type;
00471
00472 /* Create tag type object, or write attribute if opaque */
00473
00474 #if defined( H5Tcommit_vers ) && H5Tcommit_vers > 1
00475 rval = H5Tcommit2( tag_id, TAG_TYPE_NAME, hdf_type, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
00476 #else
00477 rval = H5Tcommit( tag_id, TAG_TYPE_NAME, hdf_type );
00478 #endif
00479 if( rval < 0 )
00480 {
00481 mhdf_setFail( status, "H5Tcommit failed for tag \"%s\"", tag_name );
00482 if( close_base_type ) H5Tclose( hdf_base_type );
00483 H5Tclose( hdf_type );
00484 H5Gclose( tag_id );
00485 return -1;
00486 }
00487
00488 /* If tag is entity handle, make note of it */
00489 if( tag_type == mhdf_ENTITY_ID )
00490 {
00491 rval = mhdf_create_scalar_attrib( tag_id, TAG_HANDLE_TYPE_ATTRIB, H5T_NATIVE_INT, &one, status );
00492 if( !rval )
00493 {
00494 if( close_base_type ) H5Tclose( hdf_base_type );
00495 H5Gclose( tag_id );
00496 H5Tclose( hdf_type );
00497 return -1;
00498 }
00499 }
00500
00501 /* Store the default value as a attribute of the tag group */
00502
00503 if( default_value )
00504 {
00505 rval = store_tag_val_in_attrib( tag_id, TAG_DEFAULT_ATTRIB, hdf_base_type, default_value,
00506 var_len ? default_value_size : 1, status );
00507 if( !rval )
00508 {
00509 if( close_base_type ) H5Tclose( hdf_base_type );
00510 H5Gclose( tag_id );
00511 H5Tclose( hdf_type );
00512 return -1;
00513 }
00514 }
00515
00516 /* Store global tag value as attribute */
00517
00518 if( global_value )
00519 {
00520 rval = store_tag_val_in_attrib( tag_id, TAG_GLOBAL_ATTRIB, hdf_base_type, global_value,
00521 var_len ? global_value_size : 1, status );
00522 if( !rval )
00523 {
00524 if( close_base_type ) H5Tclose( hdf_base_type );
00525 H5Gclose( tag_id );
00526 H5Tclose( hdf_type );
00527 return -1;
00528 }
00529 }
00530
00531 if( close_base_type ) H5Tclose( hdf_base_type );
00532 H5Tclose( hdf_type );
00533 mhdf_setOkay( status );
00534 return tag_id;
00535 }
00536
00537 hid_t mhdf_getTagDataType( mhdf_FileHandle file_handle, const char* tag_name, mhdf_Status* status )
00538 {
00539 FileHandle* file_ptr;
00540 hid_t result;
00541 char* path;
00542 API_BEGIN;
00543
00544 /* Validate input */
00545
00546 file_ptr = (FileHandle*)file_handle;
00547 if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
00548
00549 if( !tag_name || !*tag_name )
00550 {
00551 mhdf_setFail( status, "Invalid tag name" );
00552 return -1;
00553 }
00554
00555 /* Create path string for tag object */
00556
00557 path = mhdf_name_to_path_copy( tag_name, status );
00558 if( !path )
00559 {
00560 return -1;
00561 }
00562
00563 result = get_tag_type( file_ptr, path, status );
00564
00565 free( path );
00566 API_END;
00567 return result;
00568 }
00569
00570 void mhdf_createTag( mhdf_FileHandle file_handle,
00571 const char* tag_name,
00572 enum mhdf_TagDataType tag_type,
00573 int size,
00574 int storage,
00575 const void* default_value,
00576 const void* global_value,
00577 hid_t hdf_type,
00578 hid_t hdf_base_type,
00579 mhdf_Status* status )
00580 {
00581 hid_t tag_id;
00582 API_BEGIN;
00583 tag_id = create_tag_common( file_handle, tag_name, tag_type, size, storage, default_value, 1, global_value, 1,
00584 hdf_type, hdf_base_type, status );
00585 if( tag_id >= 0 ) H5Gclose( tag_id );
00586 API_END;
00587 }
00588
00589 void mhdf_createVarLenTag( mhdf_FileHandle file_handle,
00590 const char* tag_name,
00591 enum mhdf_TagDataType tag_type,
00592 int storage,
00593 const void* default_value,
00594 int default_value_length,
00595 const void* global_value,
00596 int global_value_length,
00597 hid_t hdf_type,
00598 hid_t hdf_base_type,
00599 mhdf_Status* status )
00600 {
00601 hid_t tag_id;
00602 int one = 1;
00603
00604 API_BEGIN;
00605 tag_id = create_tag_common( file_handle, tag_name, tag_type, -1, storage, default_value, default_value_length,
00606 global_value, global_value_length, hdf_type, hdf_base_type, status );
00607 if( tag_id >= 0 )
00608 {
00609 mhdf_create_scalar_attrib( tag_id, TAG_VARLEN_ATTRIB, H5T_NATIVE_INT, &one, status );
00610 H5Gclose( tag_id );
00611 }
00612 API_END;
00613 }
00614
00615 int mhdf_getNumberTags( mhdf_FileHandle file_handle, mhdf_Status* status )
00616 {
00617 hid_t group_id;
00618 hsize_t result;
00619 FileHandle* file_ptr;
00620 API_BEGIN;
00621
00622 /* Validate input */
00623
00624 file_ptr = (FileHandle*)file_handle;
00625 if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
00626
00627 /* Open the tags group */
00628
00629 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
00630 group_id = H5Gopen2( file_ptr->hdf_handle, TAG_GROUP, H5P_DEFAULT );
00631 #else
00632 group_id = H5Gopen( file_ptr->hdf_handle, TAG_GROUP );
00633 #endif
00634 if( group_id < 0 )
00635 {
00636 mhdf_setFail( status, "H5Gopen(\"%s\") failed", TAG_GROUP );
00637 return -1;
00638 }
00639
00640 /* Get number of objects in tags group */
00641
00642 if( H5Gget_num_objs( group_id, &result ) < 0 )
00643 {
00644 mhdf_setFail( status, "Internal failure calling H5Gget_num_objs." );
00645 H5Gclose( group_id );
00646 return -1;
00647 }
00648
00649 H5Gclose( group_id );
00650 mhdf_setOkay( status );
00651 API_END;
00652 return (int)result;
00653 }
00654
00655 char** mhdf_getTagNames( mhdf_FileHandle file_handle, int* num_names_out, mhdf_Status* status )
00656 {
00657 hid_t group_id;
00658 FileHandle* file_ptr;
00659 hsize_t count, idx;
00660 char* name;
00661 char** result;
00662 ssize_t size;
00663 API_BEGIN;
00664
00665 /* Validate input */
00666
00667 file_ptr = (FileHandle*)file_handle;
00668 if( !mhdf_check_valid_file( file_ptr, status ) ) return NULL;
00669
00670 /* Open the tags group */
00671
00672 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
00673 group_id = H5Gopen2( file_ptr->hdf_handle, TAG_GROUP, H5P_DEFAULT );
00674 #else
00675 group_id = H5Gopen( file_ptr->hdf_handle, TAG_GROUP );
00676 #endif
00677 if( group_id < 0 )
00678 {
00679 mhdf_setFail( status, "H5Gopen(\"%s\") failed", TAG_GROUP );
00680 return NULL;
00681 }
00682
00683 /* Get number of objects in tags group */
00684
00685 if( H5Gget_num_objs( group_id, &count ) < 0 )
00686 {
00687 mhdf_setFail( status, "Internal failure calling H5Gget_num_objs." );
00688 H5Gclose( group_id );
00689 return NULL;
00690 }
00691
00692 /* No tags? */
00693
00694 *num_names_out = (int)count;
00695 if( count == 0 )
00696 {
00697 H5Gclose( group_id );
00698 mhdf_setOkay( status );
00699 return NULL;
00700 }
00701
00702 /* Allocate string array */
00703
00704 result = (char**)mhdf_malloc( sizeof( char* ) * count, status );
00705 if( NULL == result )
00706 {
00707 H5Gclose( group_id );
00708 return NULL;
00709 }
00710
00711 /* Get names */
00712
00713 for( idx = 0; idx < count; ++idx )
00714 {
00715 size = H5Gget_objname_by_idx( group_id, idx, NULL, 0 );
00716 if( size < 1 || NULL == ( name = (char*)mhdf_malloc( size + 1, status ) ) )
00717 {
00718 while( ( --idx ) > 0 )
00719 free( result[idx] );
00720 free( result );
00721 H5Gclose( group_id );
00722 mhdf_setFail( status, "Internal failure calling H5Gget_objname_by_idx." );
00723 return NULL;
00724 }
00725
00726 H5Gget_objname_by_idx( group_id, idx, name, size + 1 );
00727 if( !mhdf_path_to_name( name, name ) )
00728 {
00729 mhdf_setFail( status, "Invalid character string in internal file path: \"%s\"\n", name );
00730 return NULL;
00731 }
00732 result[idx] = name;
00733 }
00734
00735 H5Gclose( group_id );
00736 mhdf_setOkay( status );
00737 API_END;
00738 return result;
00739 }
00740
00741 static int get_attrib_array_length_handle( hid_t attrib_id )
00742 {
00743 hid_t type_id;
00744 int rank;
00745 hsize_t dims[H5S_MAX_RANK];
00746 int perm[H5S_MAX_RANK];
00747
00748 type_id = H5Aget_type( attrib_id );
00749 switch( H5Tget_class( type_id ) )
00750 {
00751 case H5T_NO_CLASS:
00752 dims[0] = -1;
00753 break;
00754 case H5T_OPAQUE:
00755 dims[0] = H5Tget_size( type_id );
00756 break;
00757 case H5T_ARRAY:
00758 #if defined( H5Tget_array_dims_vers ) && H5Tget_array_dims_vers > 1
00759 (void)perm; /* suppress warning */
00760 rank = H5Tget_array_dims2( type_id, dims );
00761 #else
00762 rank = H5Tget_array_dims( type_id, dims, perm );
00763 #endif
00764 if( rank == 1 )
00765 break;
00766 else
00767 return -1;
00768 default:
00769 dims[0] = 1;
00770 break;
00771 }
00772
00773 H5Tclose( type_id );
00774 return dims[0];
00775 }
00776
00777 /*
00778 static int get_attrib_array_length_index( hid_t object_id, unsigned int index )
00779 {
00780 hid_t attrib_id;
00781 int result;
00782
00783 attrib_id = H5Aopen_idx( object_id, index );
00784 if (attrib_id < 0)
00785 return -1;
00786
00787 result = get_attrib_array_length_handle( attrib_id );
00788 H5Aclose( attrib_id );
00789 return result;
00790 }
00791 */
00792
00793 static int get_attrib_array_length_name( hid_t file, const char* path )
00794 {
00795 hid_t attrib_id;
00796 int result;
00797
00798 attrib_id = H5Aopen_name( file, path );
00799 if( attrib_id < 0 ) return -1;
00800
00801 result = get_attrib_array_length_handle( attrib_id );
00802 H5Aclose( attrib_id );
00803 return result;
00804 }
00805
00806 void mhdf_getTagInfo( mhdf_FileHandle file_handle,
00807 const char* tag_name,
00808 enum mhdf_TagDataType* class_out,
00809 int* size_out,
00810 int* tstt_storage_out,
00811 int* have_default_out,
00812 int* have_global_out,
00813 int* have_sparse_out,
00814 mhdf_Status* status )
00815 {
00816 hid_t tag_id, type_id, super_id;
00817 int i, rval, is_handle;
00818 hsize_t size, sup_size;
00819 unsigned int idx;
00820 int rank, var_data;
00821 hsize_t dims[H5S_MAX_RANK];
00822 int perm[H5S_MAX_RANK];
00823 H5T_class_t class_tmp;
00824
00825 API_BEGIN;
00826
00827 /* Validate input */
00828 if( NULL == tag_name || NULL == class_out || NULL == size_out || NULL == tstt_storage_out ||
00829 NULL == have_default_out || NULL == have_global_out || NULL == have_sparse_out )
00830 {
00831 mhdf_setFail( status, "Invalid input." );
00832 return;
00833 }
00834
00835 /* Get group for tag */
00836 tag_id = get_tag( file_handle, tag_name, NULL, status );
00837 if( tag_id < 0 ) return;
00838
00839 /* Check for sparse data */
00840 rval = mhdf_is_in_group( tag_id, SPARSE_ENTITY_NAME, status );
00841 if( rval < 0 )
00842 {
00843 H5Gclose( tag_id );
00844 return;
00845 }
00846 *have_sparse_out = rval ? 1 : 0;
00847
00848 /* Check for variable-length tag data */
00849 rval = mhdf_find_attribute( tag_id, TAG_VARLEN_ATTRIB, &idx, status );
00850 if( rval < 0 )
00851 {
00852 H5Gclose( tag_id );
00853 return;
00854 }
00855 var_data = rval ? 1 : 0;
00856
00857 /* Check if have default value for tag */
00858 rval = mhdf_find_attribute( tag_id, TAG_DEFAULT_ATTRIB, &idx, status );
00859 if( rval < 0 )
00860 {
00861 H5Gclose( tag_id );
00862 return;
00863 }
00864 if( !rval )
00865 *have_default_out = 0;
00866 else if( !var_data )
00867 *have_default_out = 1;
00868 else
00869 {
00870 /* *have_default_out = get_attrib_array_length_index( tag_id, index ); */
00871 *have_default_out = get_attrib_array_length_name( tag_id, TAG_DEFAULT_ATTRIB );
00872 if( *have_default_out < 0 )
00873 {
00874 mhdf_setFail( status, "Error checking length of default value for tag: %s\n", tag_name );
00875 H5Gclose( tag_id );
00876 return;
00877 }
00878 }
00879
00880 /* Check if have global value for tag */
00881 rval = mhdf_find_attribute( tag_id, TAG_GLOBAL_ATTRIB, &idx, status );
00882 if( rval < 0 )
00883 {
00884 H5Gclose( tag_id );
00885 return;
00886 }
00887 if( !rval )
00888 *have_global_out = 0;
00889 else if( !var_data )
00890 *have_global_out = 1;
00891 else
00892 {
00893 /* *have_global_out = get_attrib_array_length_index( tag_id, index ); */
00894 *have_global_out = get_attrib_array_length_name( tag_id, TAG_GLOBAL_ATTRIB );
00895 if( *have_global_out < 0 )
00896 {
00897 mhdf_setFail( status, "Error checking length of global value for tag: %s\n", tag_name );
00898 H5Gclose( tag_id );
00899 return;
00900 }
00901 }
00902
00903 /* Get TSTT tag class */
00904 rval = mhdf_read_scalar_attrib( tag_id, TAG_TYPE_ATTRIB, H5T_NATIVE_INT, tstt_storage_out, status );
00905 if( rval < 1 )
00906 {
00907 H5Gclose( tag_id );
00908 return;
00909 }
00910
00911 /* Check if tag is storing entity handles */
00912 rval = mhdf_find_attribute( tag_id, TAG_HANDLE_TYPE_ATTRIB, &idx, status );
00913 if( rval < 0 )
00914 {
00915 H5Gclose( tag_id );
00916 return;
00917 }
00918 is_handle = rval;
00919
00920 /* Get tag type */
00921 #if defined( H5Topen_vers ) && H5Topen_vers > 1
00922 type_id = H5Topen2( tag_id, TAG_TYPE_NAME, H5P_DEFAULT );
00923 #else
00924 type_id = H5Topen( tag_id, TAG_TYPE_NAME );
00925 #endif
00926 if( type_id < 0 )
00927 {
00928 H5Gclose( tag_id );
00929 mhdf_setFail( status, "Failed to get type object for tag \"%s\".", tag_name );
00930 return;
00931 }
00932
00933 class_tmp = H5Tget_class( type_id );
00934 if( class_tmp < 0 )
00935 {
00936 mhdf_setFail( status, "H5Tget_class failed." );
00937 H5Gclose( tag_id );
00938 H5Tclose( type_id );
00939 return;
00940 }
00941
00942 size = H5Tget_size( type_id );
00943 if( size <= 0 )
00944 {
00945 mhdf_setFail( status, "H5Tget_size failed." );
00946 H5Gclose( tag_id );
00947 H5Tclose( type_id );
00948 return;
00949 }
00950
00951 switch( class_tmp )
00952 {
00953 case H5T_INTEGER:
00954 *class_out = ( size == 1 ) ? mhdf_BOOLEAN : mhdf_INTEGER;
00955 *size_out = 1;
00956 break;
00957
00958 case H5T_FLOAT:
00959 *class_out = mhdf_FLOAT;
00960 *size_out = 1;
00961 break;
00962
00963 case H5T_BITFIELD:
00964 *class_out = mhdf_BITFIELD;
00965 *size_out = H5Tget_precision( type_id );
00966 if( *size_out <= 0 )
00967 {
00968 mhdf_setFail( status, "H5Tget_precision failed." );
00969 H5Gclose( tag_id );
00970 H5Tclose( type_id );
00971 return;
00972 }
00973 break;
00974
00975 default:
00976 case H5T_OPAQUE:
00977 *class_out = mhdf_OPAQUE;
00978 *size_out = size;
00979 break;
00980
00981 case H5T_ARRAY:
00982
00983 #if defined( H5Tget_array_dims_vers ) && H5Tget_array_dims_vers > 1
00984 (void)perm; /* suppress warning */
00985 rank = H5Tget_array_dims2( type_id, dims );
00986 #else
00987 rank = H5Tget_array_dims( type_id, dims, perm );
00988 #endif
00989 if( rank <= 0 )
00990 {
00991 mhdf_setFail( status, "H5Tget_size failed." );
00992 H5Gclose( tag_id );
00993 H5Tclose( type_id );
00994 return;
00995 }
00996 for( i = 1; i < rank; ++i )
00997 dims[0] *= dims[i];
00998
00999 super_id = H5Tget_super( type_id );
01000 if( super_id < 0 )
01001 {
01002 mhdf_setFail( status, "H5Tget_super failed" );
01003 H5Gclose( tag_id );
01004 H5Tclose( type_id );
01005 return;
01006 }
01007
01008 class_tmp = H5Tget_class( super_id );
01009 if( class_tmp < 0 )
01010 {
01011 mhdf_setFail( status, "H5Tget_class failed." );
01012 H5Gclose( tag_id );
01013 H5Tclose( type_id );
01014 H5Tclose( super_id );
01015 return;
01016 }
01017
01018 sup_size = H5Tget_size( super_id );
01019 H5Tclose( super_id );
01020 if( sup_size <= 0 )
01021 {
01022 mhdf_setFail( status, "H5Tget_size failed." );
01023 H5Gclose( tag_id );
01024 H5Tclose( type_id );
01025 return;
01026 }
01027
01028 switch( class_tmp )
01029 {
01030 case H5T_INTEGER:
01031 *class_out = ( sup_size == 1 ) ? mhdf_BOOLEAN : mhdf_INTEGER;
01032 *size_out = dims[0];
01033 break;
01034
01035 case H5T_FLOAT:
01036 *class_out = mhdf_FLOAT;
01037 *size_out = dims[0];
01038 break;
01039
01040 default:
01041 *class_out = mhdf_OPAQUE;
01042 *size_out = size;
01043 break;
01044 }
01045
01046 break;
01047 }
01048 H5Tclose( type_id );
01049 H5Gclose( tag_id );
01050
01051 if( is_handle )
01052 {
01053 if( *class_out != mhdf_INTEGER )
01054 {
01055 mhdf_setFail( status, "Non-integer tag marked as handle type." );
01056 return;
01057 }
01058 *class_out = mhdf_ENTITY_ID;
01059 }
01060
01061 if( var_data )
01062 {
01063 if( *size_out != 1 || *class_out == mhdf_BITFIELD )
01064 {
01065 mhdf_setFail( status, "Invalid or unexpected variable-length tag data" );
01066 return;
01067 }
01068 *size_out = -1;
01069 }
01070
01071 mhdf_setOkay( status );
01072 API_END;
01073 }
01074
01075 static int read_tag_attrib_data( hid_t tag_id,
01076 const char* attrib_name,
01077 hid_t type_id,
01078 void* data,
01079 int is_var_len,
01080 mhdf_Status* status )
01081 {
01082 int rval, ilen;
01083 unsigned idx;
01084 hid_t read_type = type_id;
01085 hsize_t len;
01086
01087 /* Check if tag has attribute */
01088 rval = mhdf_find_attribute( tag_id, attrib_name, &idx, status );
01089 if( rval < 0 )
01090 return 0;
01091 else if( 0 == rval )
01092 return 1;
01093
01094 if( NULL == data )
01095 {
01096 mhdf_setFail( status, "Invalid input." );
01097 return 0;
01098 }
01099
01100 if( is_var_len )
01101 {
01102 /* len = get_attrib_array_length_index(tag_id, index); */
01103 ilen = get_attrib_array_length_name( tag_id, attrib_name );
01104 if( ilen < 0 )
01105 {
01106 mhdf_setFail( status, "Failed to read length of default/mesh value for tag" );
01107 return 0;
01108 }
01109 len = ilen;
01110
01111 /* caller passes type_id == 0 for OPAQUE */
01112 if( 0 == type_id )
01113 read_type = H5Tcreate( H5T_OPAQUE, len );
01114 else
01115 {
01116 #if defined( H5Tarray_create_vers ) && H5Tarray_create_vers > 1
01117 read_type = H5Tarray_create2( type_id, 1, &len );
01118 #else
01119 read_type = H5Tarray_create( type_id, 1, &len, 0 );
01120 #endif
01121 }
01122 if( read_type < 0 )
01123 {
01124 mhdf_setFail( status, "Failed to read mesh/default value for tag" );
01125 return 0;
01126 }
01127 }
01128
01129 rval = mhdf_read_scalar_attrib( tag_id, attrib_name, read_type, data, status );
01130 if( is_var_len ) H5Tclose( read_type );
01131
01132 return rval;
01133 }
01134
01135 void mhdf_getTagValues( mhdf_FileHandle file_handle,
01136 const char* tag_name,
01137 hid_t output_data_type,
01138 void* default_value,
01139 void* global_value,
01140 mhdf_Status* status )
01141 {
01142 hid_t tag_id;
01143 int rval, var_data;
01144 unsigned int idx;
01145 API_BEGIN;
01146
01147 /* check args */
01148 if( NULL == tag_name || !*tag_name )
01149 {
01150 mhdf_setFail( status, "Invalid input." );
01151 return;
01152 }
01153
01154 /* Get the tag group */
01155 tag_id = get_tag( file_handle, tag_name, NULL, status );
01156 if( tag_id < 0 ) return;
01157
01158 /* Check for variable-length tag data */
01159 rval = mhdf_find_attribute( tag_id, TAG_VARLEN_ATTRIB, &idx, status );
01160 if( rval < 0 )
01161 {
01162 H5Gclose( tag_id );
01163 return;
01164 }
01165 var_data = rval ? 1 : 0;
01166
01167 /* Read default value if present */
01168 rval = read_tag_attrib_data( tag_id, TAG_DEFAULT_ATTRIB, output_data_type, default_value, var_data, status );
01169 if( !rval )
01170 {
01171 H5Gclose( tag_id );
01172 return;
01173 }
01174
01175 /* Read mesh value if present */
01176 rval = read_tag_attrib_data( tag_id, TAG_GLOBAL_ATTRIB, output_data_type, global_value, var_data, status );
01177 if( !rval )
01178 {
01179 H5Gclose( tag_id );
01180 return;
01181 }
01182
01183 H5Gclose( tag_id );
01184 mhdf_setOkay( status );
01185 API_END;
01186 }
01187
01188 int mhdf_haveDenseTag( mhdf_FileHandle file_handle, const char* tag_name, const char* type_handle, mhdf_Status* status )
01189 {
01190 char* path;
01191 hid_t elem_id, group_id;
01192 FileHandle* file_ptr;
01193 int rval = 0;
01194 API_BEGIN;
01195
01196 file_ptr = (FileHandle*)file_handle;
01197 if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
01198
01199 if( type_handle == mhdf_node_type_handle() )
01200 {
01201 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
01202 elem_id = H5Gopen2( file_ptr->hdf_handle, NODE_GROUP, H5P_DEFAULT );
01203 #else
01204 elem_id = H5Gopen( file_ptr->hdf_handle, NODE_GROUP );
01205 #endif
01206 if( elem_id < 0 ) mhdf_setFail( status, "Could not open node group." );
01207 }
01208 else if( type_handle == mhdf_set_type_handle() )
01209 {
01210 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
01211 elem_id = H5Gopen2( file_ptr->hdf_handle, SET_GROUP, H5P_DEFAULT );
01212 #else
01213 elem_id = H5Gopen( file_ptr->hdf_handle, SET_GROUP );
01214 #endif
01215 if( elem_id < 0 ) mhdf_setFail( status, "Could not open set group." );
01216 }
01217 else
01218 {
01219 elem_id = mhdf_elem_group_from_handle( file_ptr, type_handle, status );
01220 }
01221 if( elem_id < 0 ) return -1;
01222
01223 rval = mhdf_is_in_group( elem_id, TAG_GROUP_NAME, status );
01224 if( rval < 0 )
01225 {
01226 H5Gclose( elem_id );
01227 return -1;
01228 }
01229 else if( rval == 0 )
01230 {
01231 H5Gclose( elem_id );
01232 mhdf_setOkay( status );
01233 return 0;
01234 }
01235
01236 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
01237 group_id = H5Gopen2( elem_id, DENSE_TAG_SUBGROUP, H5P_DEFAULT );
01238 #else
01239 group_id = H5Gopen( elem_id, DENSE_TAG_SUBGROUP );
01240 #endif
01241 H5Gclose( elem_id );
01242 if( group_id < 0 )
01243 {
01244 mhdf_setFail( status, "Could not open tag subgroup." );
01245 return -1;
01246 }
01247
01248 path = mhdf_name_to_path_copy( tag_name, status );
01249 if( NULL == path )
01250 {
01251 H5Gclose( group_id );
01252 return -1;
01253 }
01254
01255 rval = mhdf_is_in_group( group_id, path, status );
01256 H5Gclose( group_id );
01257 free( path );
01258
01259 if( rval >= 0 )
01260 {
01261 mhdf_setOkay( status );
01262 }
01263
01264 API_END;
01265 return rval;
01266 }
01267
01268 hid_t mhdf_createDenseTagData( mhdf_FileHandle file_handle,
01269 const char* tag_name,
01270 const char* type_handle,
01271 long num_values,
01272 mhdf_Status* status )
01273 {
01274 char* path;
01275 hid_t elem_id, data_id, type_id;
01276 FileHandle* file_ptr;
01277 size_t name_len, path_len, dir_len;
01278 hsize_t size;
01279 API_BEGIN;
01280
01281 file_ptr = (FileHandle*)file_handle;
01282 if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
01283
01284 if( type_handle == mhdf_node_type_handle() )
01285 {
01286 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
01287 elem_id = H5Gopen2( file_ptr->hdf_handle, NODE_GROUP, H5P_DEFAULT );
01288 #else
01289 elem_id = H5Gopen( file_ptr->hdf_handle, NODE_GROUP );
01290 #endif
01291 if( elem_id < 0 ) mhdf_setFail( status, "Could not open node group." );
01292 }
01293 else if( type_handle == mhdf_set_type_handle() )
01294 {
01295 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
01296 elem_id = H5Gopen2( file_ptr->hdf_handle, SET_GROUP, H5P_DEFAULT );
01297 #else
01298 elem_id = H5Gopen( file_ptr->hdf_handle, SET_GROUP );
01299 #endif
01300 if( elem_id < 0 ) mhdf_setFail( status, "Could not open set group." );
01301 }
01302 else
01303 {
01304 elem_id = mhdf_elem_group_from_handle( file_ptr, type_handle, status );
01305 }
01306 if( elem_id < 0 ) return -1;
01307
01308 dir_len = strlen( DENSE_TAG_SUBGROUP );
01309 name_len = mhdf_name_to_path( tag_name, NULL, 0 );
01310 path_len = dir_len + name_len + 1;
01311 path = (char*)mhdf_malloc( path_len, status );
01312 if( NULL == path )
01313 {
01314 H5Gclose( elem_id );
01315 return -1;
01316 }
01317 strcpy( path, DENSE_TAG_SUBGROUP );
01318 mhdf_name_to_path( tag_name, path + dir_len, name_len + 1 );
01319
01320 type_id = get_tag_type( file_ptr, path + dir_len, status );
01321 if( type_id < 0 )
01322 {
01323 H5Gclose( elem_id );
01324 return -1;
01325 }
01326
01327 size = (hsize_t)num_values;
01328 data_id = mhdf_create_table( elem_id, path, type_id, 1, &size, status );
01329 free( path );
01330 H5Gclose( elem_id );
01331 H5Tclose( type_id );
01332
01333 if( data_id > 0 ) mhdf_setOkay( status );
01334
01335 API_END_H( 1 );
01336 return data_id;
01337 }
01338
01339 hid_t mhdf_openDenseTagData( mhdf_FileHandle file_handle,
01340 const char* tag_name,
01341 const char* type_handle,
01342 long* num_values_out,
01343 mhdf_Status* status )
01344 {
01345 char* path;
01346 hid_t elem_id, data_id;
01347 FileHandle* file_ptr;
01348 size_t name_len, path_len, dir_len;
01349 hsize_t size;
01350 API_BEGIN;
01351
01352 file_ptr = (FileHandle*)file_handle;
01353 if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
01354
01355 if( type_handle == mhdf_node_type_handle() )
01356 {
01357 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
01358 elem_id = H5Gopen2( file_ptr->hdf_handle, NODE_GROUP, H5P_DEFAULT );
01359 #else
01360 elem_id = H5Gopen( file_ptr->hdf_handle, NODE_GROUP );
01361 #endif
01362 if( elem_id < 0 ) mhdf_setFail( status, "Could not open node group." );
01363 }
01364 else if( type_handle == mhdf_set_type_handle() )
01365 {
01366 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
01367 elem_id = H5Gopen2( file_ptr->hdf_handle, SET_GROUP, H5P_DEFAULT );
01368 #else
01369 elem_id = H5Gopen( file_ptr->hdf_handle, SET_GROUP );
01370 #endif
01371 if( elem_id < 0 ) mhdf_setFail( status, "Could not open set group." );
01372 }
01373 else
01374 {
01375 elem_id = mhdf_elem_group_from_handle( file_ptr, type_handle, status );
01376 }
01377 if( elem_id < 0 ) return -1;
01378
01379 dir_len = strlen( DENSE_TAG_SUBGROUP );
01380 name_len = mhdf_name_to_path( tag_name, NULL, 0 );
01381 path_len = dir_len + name_len + 1;
01382 path = (char*)mhdf_malloc( path_len, status );
01383 if( NULL == path )
01384 {
01385 H5Gclose( elem_id );
01386 return -1;
01387 }
01388 strcpy( path, DENSE_TAG_SUBGROUP );
01389 mhdf_name_to_path( tag_name, path + dir_len, name_len + 1 );
01390
01391 data_id = mhdf_open_table( elem_id, path, 1, &size, status );
01392 free( path );
01393 H5Gclose( elem_id );
01394 *num_values_out = (long)size;
01395
01396 if( data_id >= 0 ) mhdf_setOkay( status );
01397
01398 API_END_H( 1 );
01399 return data_id;
01400 }
01401
01402 void mhdf_createSparseTagData( mhdf_FileHandle file_handle,
01403 const char* tag_name,
01404 long num_values,
01405 hid_t handles_out[2],
01406 mhdf_Status* status )
01407 {
01408 hid_t tag_id, index_id, data_id, type_id, id_type;
01409 hsize_t count = (hsize_t)num_values;
01410 API_BEGIN;
01411
01412 tag_id = get_tag( file_handle, tag_name, &id_type, status );
01413 if( tag_id < 0 ) return;
01414
01415 #if defined( H5Topen_vers ) && H5Topen_vers > 1
01416 type_id = H5Topen2( tag_id, TAG_TYPE_NAME, H5P_DEFAULT );
01417 #else
01418 type_id = H5Topen( tag_id, TAG_TYPE_NAME );
01419 #endif
01420 if( type_id < 0 )
01421 {
01422 H5Gclose( tag_id );
01423 mhdf_setFail( status, "Failed to get type object for tag \"%s\".", tag_name );
01424 return;
01425 }
01426
01427 index_id = mhdf_create_table( tag_id, SPARSE_ENTITY_NAME, id_type, 1, &count, status );
01428 if( index_id < 0 )
01429 {
01430 H5Gclose( tag_id );
01431 H5Tclose( type_id );
01432 return;
01433 }
01434
01435 data_id = mhdf_create_table( tag_id, SPARSE_VALUES_NAME, type_id, 1, &count, status );
01436 H5Tclose( type_id );
01437 H5Gclose( tag_id );
01438 if( data_id < 0 )
01439 {
01440 H5Dclose( index_id );
01441 return;
01442 }
01443
01444 handles_out[0] = index_id;
01445 handles_out[1] = data_id;
01446 mhdf_setOkay( status );
01447 API_END_H( 2 );
01448 }
01449
01450 void mhdf_createVarLenTagData( mhdf_FileHandle file_handle,
01451 const char* tag_name,
01452 long num_entities,
01453 long num_values,
01454 hid_t handles_out[3],
01455 mhdf_Status* status )
01456 {
01457 hid_t tag_id, index_id, data_id, type_id, offset_id, id_type;
01458 hsize_t count = (hsize_t)num_entities;
01459 API_BEGIN;
01460
01461 tag_id = get_tag( file_handle, tag_name, &id_type, status );
01462 if( tag_id < 0 ) return;
01463
01464 #if defined( H5Topen_vers ) && H5Topen_vers > 1
01465 type_id = H5Topen2( tag_id, TAG_TYPE_NAME, H5P_DEFAULT );
01466 #else
01467 type_id = H5Topen( tag_id, TAG_TYPE_NAME );
01468 #endif
01469 if( type_id < 0 )
01470 {
01471 H5Gclose( tag_id );
01472 mhdf_setFail( status, "Failed to get type object for tag \"%s\".", tag_name );
01473 return;
01474 }
01475
01476 index_id = mhdf_create_table( tag_id, SPARSE_ENTITY_NAME, id_type, 1, &count, status );
01477 if( index_id < 0 )
01478 {
01479 H5Gclose( tag_id );
01480 H5Tclose( type_id );
01481 return;
01482 }
01483
01484 offset_id = mhdf_create_table( tag_id, TAG_VAR_INDICES, MHDF_INDEX_TYPE, 1, &count, status );
01485 if( index_id < 0 )
01486 {
01487 H5Dclose( offset_id );
01488 H5Gclose( tag_id );
01489 H5Tclose( type_id );
01490 return;
01491 }
01492
01493 count = (hsize_t)num_values;
01494 data_id = mhdf_create_table( tag_id, SPARSE_VALUES_NAME, type_id, 1, &count, status );
01495 H5Tclose( type_id );
01496 H5Gclose( tag_id );
01497 if( data_id < 0 )
01498 {
01499 H5Dclose( offset_id );
01500 H5Dclose( index_id );
01501 return;
01502 }
01503
01504 handles_out[0] = index_id;
01505 handles_out[1] = data_id;
01506 handles_out[2] = offset_id;
01507 mhdf_setOkay( status );
01508 API_END_H( 3 );
01509 }
01510
01511 void mhdf_openSparseTagData( mhdf_FileHandle file_handle,
01512 const char* tag_name,
01513 long* num_entity_out,
01514 long* num_values_out,
01515 hid_t handles_out[3],
01516 mhdf_Status* status )
01517 {
01518 hid_t tag_id, index_id, data_id, offset_id = -1;
01519 hsize_t num_ent, data_size, num_data;
01520 int rval;
01521 unsigned idx;
01522 API_BEGIN;
01523
01524 tag_id = get_tag( file_handle, tag_name, NULL, status );
01525 if( tag_id < 0 ) return;
01526
01527 index_id = mhdf_open_table( tag_id, SPARSE_ENTITY_NAME, 1, &num_ent, status );
01528 if( index_id < 0 )
01529 {
01530 H5Gclose( tag_id );
01531 return;
01532 }
01533
01534 data_id = mhdf_open_table( tag_id, SPARSE_VALUES_NAME, 1, &data_size, status );
01535 if( data_id < 0 )
01536 {
01537 H5Gclose( tag_id );
01538 H5Dclose( index_id );
01539 return;
01540 }
01541
01542 /* check if tag is variable-lentgth */
01543 rval = mhdf_find_attribute( tag_id, TAG_VARLEN_ATTRIB, &idx, status );
01544 if( rval < 0 )
01545 {
01546 H5Gclose( tag_id );
01547 H5Dclose( index_id );
01548 H5Dclose( data_id );
01549 return;
01550 }
01551
01552 /* If variable length... */
01553 if( rval )
01554 {
01555 offset_id = mhdf_open_table( tag_id, TAG_VAR_INDICES, 1, &num_data, status );
01556 if( offset_id < 0 )
01557 {
01558 H5Gclose( tag_id );
01559 H5Dclose( index_id );
01560 H5Dclose( data_id );
01561 return;
01562 }
01563 }
01564 /* Otherwise the number of values is the same as the size of the data table */
01565 else
01566 {
01567 num_data = data_size;
01568 }
01569
01570 H5Gclose( tag_id );
01571 if( num_ent != num_data )
01572 {
01573 mhdf_setFail( status, "Data length mismatch for sparse tag data -- invalid file." );
01574 if( offset_id >= 0 ) H5Dclose( offset_id );
01575 H5Dclose( index_id );
01576 H5Dclose( data_id );
01577 return;
01578 }
01579 *num_entity_out = (long)num_ent;
01580 if( num_values_out ) *num_values_out = (long)data_size;
01581
01582 handles_out[0] = index_id;
01583 handles_out[1] = data_id;
01584 if( offset_id >= 0 ) handles_out[2] = offset_id;
01585 mhdf_setOkay( status );
01586 API_END_H( 2 );
01587 }
01588
01589 void mhdf_writeSparseTagEntities( hid_t table_id,
01590 long offset,
01591 long count,
01592 hid_t int_type,
01593 const void* id_list,
01594 mhdf_Status* status )
01595 {
01596 API_BEGIN;
01597 mhdf_write_data( table_id, offset, count, int_type, id_list, H5P_DEFAULT, status );
01598 API_END;
01599 }
01600 void mhdf_writeSparseTagEntitiesWithOpt( hid_t table_id,
01601 long offset,
01602 long count,
01603 hid_t int_type,
01604 const void* id_list,
01605 hid_t io_prop,
01606 mhdf_Status* status )
01607 {
01608 API_BEGIN;
01609 mhdf_write_data( table_id, offset, count, int_type, id_list, io_prop, status );
01610 API_END;
01611 }
01612
01613 void mhdf_writeTagValues( hid_t table_id,
01614 long offset,
01615 long count,
01616 hid_t tag_type,
01617 const void* tag_data,
01618 mhdf_Status* status )
01619 {
01620 mhdf_writeTagValuesWithOpt( table_id, offset, count, tag_type, tag_data, H5P_DEFAULT, status );
01621 }
01622
01623 void mhdf_writeTagValuesWithOpt( hid_t table_id,
01624 long offset,
01625 long count,
01626 hid_t tag_type,
01627 const void* tag_data,
01628 hid_t io_prop,
01629 mhdf_Status* status )
01630 {
01631 API_BEGIN;
01632 mhdf_write_data( table_id, offset, count, tag_type, tag_data, io_prop, status );
01633 API_END;
01634 }
01635
01636 void mhdf_writeSparseTagIndices( hid_t table_id,
01637 long offset,
01638 long count,
01639 hid_t int_type,
01640 const void* indices,
01641 mhdf_Status* status )
01642 {
01643 API_BEGIN;
01644 mhdf_write_data( table_id, offset, count, int_type, indices, H5P_DEFAULT, status );
01645 API_END;
01646 }
01647 void mhdf_writeSparseTagIndicesWithOpt( hid_t table_id,
01648 long offset,
01649 long count,
01650 hid_t int_type,
01651 const void* indices,
01652 hid_t io_prop,
01653 mhdf_Status* status )
01654 {
01655 API_BEGIN;
01656 mhdf_write_data( table_id, offset, count, int_type, indices, io_prop, status );
01657 API_END;
01658 }
01659
01660 void mhdf_readSparseTagEntities( hid_t table_id,
01661 long offset,
01662 long count,
01663 hid_t int_type,
01664 void* id_list,
01665 mhdf_Status* status )
01666 {
01667 API_BEGIN;
01668 mhdf_read_data( table_id, offset, count, int_type, id_list, H5P_DEFAULT, status );
01669 API_END;
01670 }
01671 void mhdf_readSparseTagEntitiesWithOpt( hid_t table_id,
01672 long offset,
01673 long count,
01674 hid_t int_type,
01675 void* id_list,
01676 hid_t io_prop,
01677 mhdf_Status* status )
01678 {
01679 API_BEGIN;
01680 mhdf_read_data( table_id, offset, count, int_type, id_list, io_prop, status );
01681 API_END;
01682 }
01683
01684 void mhdf_readTagValues( hid_t table_id, long offset, long count, hid_t tag_type, void* tag_data, mhdf_Status* status )
01685 {
01686 mhdf_readTagValuesWithOpt( table_id, offset, count, tag_type, tag_data, H5P_DEFAULT, status );
01687 }
01688 void mhdf_readTagValuesWithOpt( hid_t table_id,
01689 long offset,
01690 long count,
01691 hid_t tag_type,
01692 void* tag_data,
01693 hid_t io_prop,
01694 mhdf_Status* status )
01695 {
01696 API_BEGIN;
01697 mhdf_read_data( table_id, offset, count, tag_type, tag_data, io_prop, status );
01698 API_END;
01699 }
01700
01701 void mhdf_readSparseTagIndices( hid_t table_id,
01702 long offset,
01703 long count,
01704 hid_t int_type,
01705 void* indices,
01706 mhdf_Status* status )
01707 {
01708 API_BEGIN;
01709 mhdf_read_data( table_id, offset, count, int_type, indices, H5P_DEFAULT, status );
01710 API_END;
01711 }
01712 void mhdf_readSparseTagIndicesWithOpt( hid_t table_id,
01713 long offset,
01714 long count,
01715 hid_t int_type,
01716 void* indices,
01717 hid_t io_prop,
01718 mhdf_Status* status )
01719 {
01720 API_BEGIN;
01721 mhdf_read_data( table_id, offset, count, int_type, indices, io_prop, status );
01722 API_END;
01723 }