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 <stdlib.h> 00017 #include <string.h> 00018 #include <H5Tpublic.h> 00019 #include <H5Gpublic.h> 00020 #include <H5Dpublic.h> 00021 #include <H5Spublic.h> /* for H5S_MAX_RANK */ 00022 #include <H5Apublic.h> 00023 #include <H5Ppublic.h> 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 }