MOAB: Mesh Oriented datABase
(version 5.2.1)
|
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, const char* attrib_name, hid_t type_id, const void* value, 00200 hsize_t value_size, mhdf_Status* status ) 00201 { 00202 hid_t write_type; 00203 int rval; 00204 if( value_size == 1 ) 00205 write_type = type_id; 00206 else if( H5Tget_class( type_id ) == H5T_OPAQUE ) 00207 { 00208 write_type = H5Tcreate( H5T_OPAQUE, value_size ); 00209 } 00210 else 00211 { 00212 #if defined( H5Tarray_create_vers ) && H5Tarray_create_vers > 1 00213 write_type = H5Tarray_create2( type_id, 1, &value_size ); 00214 #else 00215 write_type = H5Tarray_create( type_id, 1, &value_size, 0 ); 00216 #endif 00217 } 00218 00219 if( write_type < 0 ) 00220 { 00221 mhdf_setFail( status, "Error constructing type object for tag mesh/default value" ); 00222 return -1; 00223 } 00224 00225 rval = mhdf_create_scalar_attrib( tag_id, attrib_name, write_type, value, status ); 00226 if( write_type != type_id ) H5Tclose( write_type ); 00227 00228 return rval; 00229 } 00230 00231 static hid_t create_tag_common( mhdf_FileHandle file_handle, const char* tag_name, enum mhdf_TagDataType tag_type, 00232 int size, int storage, const void* default_value, int default_value_size_in, 00233 const void* global_value, int global_value_size_in, hid_t hdf_type, hid_t hdf_base_type, 00234 mhdf_Status* status ) 00235 { 00236 hid_t temp_id, group_id, tag_id; 00237 char* path; 00238 FileHandle* file_ptr; 00239 herr_t rval; 00240 hsize_t arr_len; 00241 int one = 1, var_len = 0; 00242 hsize_t default_value_size = default_value_size_in; 00243 hsize_t global_value_size = global_value_size_in; 00244 int close_base_type = 0; 00245 00246 /* Force standard data types over user-specified types */ 00247 00248 if( tag_type != mhdf_OPAQUE ) hdf_type = 0; 00249 if( tag_type != mhdf_ENTITY_ID ) hdf_base_type = 0; 00250 00251 /* Validate input */ 00252 00253 file_ptr = (FileHandle*)file_handle; 00254 if( !mhdf_check_valid_file( file_ptr, status ) ) return -1; 00255 00256 if( !tag_name || !*tag_name ) 00257 { 00258 mhdf_setFail( status, "Invalid tag name" ); 00259 return -1; 00260 } 00261 00262 /* Open the tag group */ 00263 00264 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1 00265 group_id = H5Gopen2( file_ptr->hdf_handle, TAG_GROUP, H5P_DEFAULT ); 00266 #else 00267 group_id = H5Gopen( file_ptr->hdf_handle, TAG_GROUP ); 00268 #endif 00269 if( group_id < 0 ) 00270 { 00271 mhdf_setFail( status, "H5Gopen(\"%s\") failed.", TAG_GROUP ); 00272 return -1; 00273 } 00274 00275 /* Create path string for tag object */ 00276 00277 path = mhdf_name_to_path_copy( tag_name, status ); 00278 if( !path ) 00279 { 00280 H5Gclose( group_id ); 00281 return -1; 00282 } 00283 00284 /* Create group for this tag */ 00285 00286 #if defined( H5Gcreate_vers ) && H5Gcreate_vers > 1 00287 tag_id = H5Gcreate2( group_id, path, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT ); 00288 #else 00289 tag_id = H5Gcreate( group_id, path, 3 ); 00290 #endif 00291 if( tag_id < 0 ) 00292 { 00293 mhdf_setFail( status, "H5Gcreate( \"%s\" ) failed.", path ); 00294 free( path ); 00295 H5Gclose( group_id ); 00296 return -1; 00297 } 00298 00299 /* Store the tag name as the comment on the group entry */ 00300 00301 rval = H5Gset_comment( group_id, path, tag_name ); 00302 H5Gclose( group_id ); 00303 free( path ); 00304 if( rval < 0 ) 00305 { 00306 mhdf_setFail( status, "H5Gset_comment failed for tag \"%s\"", tag_name ); 00307 H5Gclose( tag_id ); 00308 return -1; 00309 } 00310 00311 /* Store TSTT tag type as attribute */ 00312 00313 rval = mhdf_create_scalar_attrib( tag_id, TAG_TYPE_ATTRIB, H5T_NATIVE_INT, &storage, status ); 00314 if( !rval ) 00315 { 00316 H5Gclose( tag_id ); 00317 return -1; 00318 } 00319 00320 if( hdf_type ) 00321 { 00322 hdf_type = H5Tcopy( hdf_type ); 00323 arr_len = 1; 00324 } 00325 else 00326 { 00327 switch( tag_type ) 00328 { 00329 default: 00330 case mhdf_OPAQUE: 00331 arr_len = 1; 00332 hdf_type = H5Tcreate( H5T_OPAQUE, abs( size ) ); 00333 H5Tset_tag( hdf_type, "tag_data" ); 00334 break; 00335 00336 case mhdf_BITFIELD: 00337 arr_len = 1; 00338 if( size <= 0 ) 00339 { 00340 mhdf_setFail( status, "Invalid size (%d) for bit tag.", (int)size ); 00341 return -1; 00342 } 00343 else if( size <= 8 ) 00344 hdf_type = H5Tcopy( H5T_NATIVE_B8 ); 00345 else if( size <= 16 ) 00346 hdf_type = H5Tcopy( H5T_NATIVE_B16 ); 00347 else if( size <= 32 ) 00348 hdf_type = H5Tcopy( H5T_NATIVE_B32 ); 00349 else if( size <= 64 ) 00350 hdf_type = H5Tcopy( H5T_NATIVE_B64 ); 00351 else 00352 { 00353 mhdf_setFail( status, "Cannot create a bit tag larger than 64-bits. %d bits requested.\n", 00354 (int)size ); 00355 return -1; 00356 } 00357 00358 if( 0 > H5Tset_precision( hdf_type, size ) ) 00359 { 00360 mhdf_setFail( status, "H5Tset_precision failed." ); 00361 return -1; 00362 } 00363 break; 00364 00365 case mhdf_ENTITY_ID: 00366 arr_len = abs( size ); 00367 hdf_type = H5Tcopy( H5T_NATIVE_ULONG ); 00368 break; 00369 00370 case mhdf_BOOLEAN: 00371 arr_len = abs( size ); 00372 hdf_type = H5Tcopy( H5T_NATIVE_UCHAR ); 00373 break; 00374 00375 case mhdf_INTEGER: 00376 arr_len = abs( size ); 00377 hdf_type = H5Tcopy( H5T_NATIVE_INT ); 00378 break; 00379 00380 case mhdf_FLOAT: 00381 arr_len = abs( size ); 00382 hdf_type = H5Tcopy( H5T_NATIVE_DOUBLE ); 00383 break; 00384 } 00385 } 00386 00387 if( hdf_type <= 0 ) 00388 { 00389 mhdf_setFail( status, "Failed to create tag type object." ); 00390 H5Gclose( tag_id ); 00391 return -1; 00392 } 00393 00394 if( hdf_base_type && H5Tget_class( hdf_type ) != H5Tget_class( hdf_base_type ) ) 00395 { 00396 mhdf_setFail( status, "Invalid base type for tag default/global data" ); 00397 H5Gclose( tag_id ); 00398 return -1; 00399 } 00400 00401 if( size < -1 || !arr_len ) 00402 { 00403 mhdf_setFail( status, "Invalid 'size' parameter passed to mhdf_createTag (%d)", (int)size ); 00404 H5Gclose( tag_id ); 00405 return -1; 00406 } 00407 else if( size == -1 ) 00408 { 00409 /* Note: we don't do anything with this here. We rely on 00410 * the app to ask us to create the index table later. 00411 */ 00412 arr_len = 1; 00413 /* need to know this later, when storing default/global values */ 00414 var_len = 1; 00415 } 00416 else if( arr_len > 1 ) 00417 { 00418 #if defined( H5Tarray_create_vers ) && H5Tarray_create_vers > 1 00419 temp_id = H5Tarray_create2( hdf_type, 1, &arr_len ); 00420 #else 00421 temp_id = H5Tarray_create( hdf_type, 1, &arr_len, NULL ); 00422 #endif 00423 H5Tclose( hdf_type ); 00424 if( temp_id < 0 ) 00425 { 00426 mhdf_setFail( status, "Failed to create tag type object." ); 00427 H5Gclose( tag_id ); 00428 return -1; 00429 } 00430 hdf_type = temp_id; 00431 00432 if( hdf_base_type ) 00433 { 00434 if( H5Tequal( hdf_base_type, hdf_type ) > 0 ) { hdf_base_type = hdf_type; } 00435 else 00436 { 00437 #if defined( H5Tarray_create_vers ) && H5Tarray_create_vers > 1 00438 temp_id = H5Tarray_create2( hdf_base_type, 1, &arr_len ); 00439 #else 00440 temp_id = H5Tarray_create( hdf_base_type, 1, &arr_len, NULL ); 00441 #endif 00442 if( temp_id < 0 ) 00443 { 00444 mhdf_setFail( status, "Failed to create tag type object." ); 00445 H5Gclose( tag_id ); 00446 H5Tclose( hdf_type ); 00447 return -1; 00448 } 00449 hdf_base_type = temp_id; 00450 close_base_type = 1; 00451 } 00452 } 00453 } 00454 00455 if( !hdf_base_type ) hdf_base_type = hdf_type; 00456 00457 /* Create tag type object, or write attribute if opaque */ 00458 00459 #if defined( H5Tcommit_vers ) && H5Tcommit_vers > 1 00460 rval = H5Tcommit2( tag_id, TAG_TYPE_NAME, hdf_type, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT ); 00461 #else 00462 rval = H5Tcommit( tag_id, TAG_TYPE_NAME, hdf_type ); 00463 #endif 00464 if( rval < 0 ) 00465 { 00466 mhdf_setFail( status, "H5Tcommit failed for tag \"%s\"", tag_name ); 00467 if( close_base_type ) H5Tclose( hdf_base_type ); 00468 H5Tclose( hdf_type ); 00469 H5Gclose( tag_id ); 00470 return -1; 00471 } 00472 00473 /* If tag is entity handle, make note of it */ 00474 if( tag_type == mhdf_ENTITY_ID ) 00475 { 00476 rval = mhdf_create_scalar_attrib( tag_id, TAG_HANDLE_TYPE_ATTRIB, H5T_NATIVE_INT, &one, status ); 00477 if( !rval ) 00478 { 00479 if( close_base_type ) H5Tclose( hdf_base_type ); 00480 H5Gclose( tag_id ); 00481 H5Tclose( hdf_type ); 00482 return -1; 00483 } 00484 } 00485 00486 /* Store the default value as a attribute of the tag group */ 00487 00488 if( default_value ) 00489 { 00490 rval = store_tag_val_in_attrib( tag_id, TAG_DEFAULT_ATTRIB, hdf_base_type, default_value, 00491 var_len ? default_value_size : 1, 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 global tag value as attribute */ 00502 00503 if( global_value ) 00504 { 00505 rval = store_tag_val_in_attrib( tag_id, TAG_GLOBAL_ATTRIB, hdf_base_type, global_value, 00506 var_len ? global_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 if( close_base_type ) H5Tclose( hdf_base_type ); 00517 H5Tclose( hdf_type ); 00518 mhdf_setOkay( status ); 00519 return tag_id; 00520 } 00521 00522 hid_t mhdf_getTagDataType( mhdf_FileHandle file_handle, const char* tag_name, mhdf_Status* status ) 00523 { 00524 FileHandle* file_ptr; 00525 hid_t result; 00526 char* path; 00527 API_BEGIN; 00528 00529 /* Validate input */ 00530 00531 file_ptr = (FileHandle*)file_handle; 00532 if( !mhdf_check_valid_file( file_ptr, status ) ) return -1; 00533 00534 if( !tag_name || !*tag_name ) 00535 { 00536 mhdf_setFail( status, "Invalid tag name" ); 00537 return -1; 00538 } 00539 00540 /* Create path string for tag object */ 00541 00542 path = mhdf_name_to_path_copy( tag_name, status ); 00543 if( !path ) { return -1; } 00544 00545 result = get_tag_type( file_ptr, path, status ); 00546 00547 free( path ); 00548 API_END; 00549 return result; 00550 } 00551 00552 void mhdf_createTag( mhdf_FileHandle file_handle, const char* tag_name, enum mhdf_TagDataType tag_type, int size, 00553 int storage, const void* default_value, const void* global_value, hid_t hdf_type, 00554 hid_t hdf_base_type, mhdf_Status* status ) 00555 { 00556 hid_t tag_id; 00557 API_BEGIN; 00558 tag_id = create_tag_common( file_handle, tag_name, tag_type, size, storage, default_value, 1, global_value, 1, 00559 hdf_type, hdf_base_type, status ); 00560 if( tag_id >= 0 ) H5Gclose( tag_id ); 00561 API_END; 00562 } 00563 00564 void mhdf_createVarLenTag( mhdf_FileHandle file_handle, const char* tag_name, enum mhdf_TagDataType tag_type, 00565 int storage, const void* default_value, int default_value_length, const void* global_value, 00566 int global_value_length, hid_t hdf_type, hid_t hdf_base_type, mhdf_Status* status ) 00567 { 00568 hid_t tag_id; 00569 int one = 1; 00570 00571 API_BEGIN; 00572 tag_id = create_tag_common( file_handle, tag_name, tag_type, -1, storage, default_value, default_value_length, 00573 global_value, global_value_length, hdf_type, hdf_base_type, status ); 00574 if( tag_id >= 0 ) 00575 { 00576 mhdf_create_scalar_attrib( tag_id, TAG_VARLEN_ATTRIB, H5T_NATIVE_INT, &one, status ); 00577 H5Gclose( tag_id ); 00578 } 00579 API_END; 00580 } 00581 00582 int mhdf_getNumberTags( mhdf_FileHandle file_handle, mhdf_Status* status ) 00583 { 00584 hid_t group_id; 00585 hsize_t result; 00586 FileHandle* file_ptr; 00587 API_BEGIN; 00588 00589 /* Validate input */ 00590 00591 file_ptr = (FileHandle*)file_handle; 00592 if( !mhdf_check_valid_file( file_ptr, status ) ) return -1; 00593 00594 /* Open the tags group */ 00595 00596 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1 00597 group_id = H5Gopen2( file_ptr->hdf_handle, TAG_GROUP, H5P_DEFAULT ); 00598 #else 00599 group_id = H5Gopen( file_ptr->hdf_handle, TAG_GROUP ); 00600 #endif 00601 if( group_id < 0 ) 00602 { 00603 mhdf_setFail( status, "H5Gopen(\"%s\") failed", TAG_GROUP ); 00604 return -1; 00605 } 00606 00607 /* Get number of objects in tags group */ 00608 00609 if( H5Gget_num_objs( group_id, &result ) < 0 ) 00610 { 00611 mhdf_setFail( status, "Internal failure calling H5Gget_num_objs." ); 00612 H5Gclose( group_id ); 00613 return -1; 00614 } 00615 00616 H5Gclose( group_id ); 00617 mhdf_setOkay( status ); 00618 API_END; 00619 return (int)result; 00620 } 00621 00622 char** mhdf_getTagNames( mhdf_FileHandle file_handle, int* num_names_out, mhdf_Status* status ) 00623 { 00624 hid_t group_id; 00625 FileHandle* file_ptr; 00626 hsize_t count, idx; 00627 char* name; 00628 char** result; 00629 ssize_t size; 00630 API_BEGIN; 00631 00632 /* Validate input */ 00633 00634 file_ptr = (FileHandle*)file_handle; 00635 if( !mhdf_check_valid_file( file_ptr, status ) ) return NULL; 00636 00637 /* Open the tags group */ 00638 00639 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1 00640 group_id = H5Gopen2( file_ptr->hdf_handle, TAG_GROUP, H5P_DEFAULT ); 00641 #else 00642 group_id = H5Gopen( file_ptr->hdf_handle, TAG_GROUP ); 00643 #endif 00644 if( group_id < 0 ) 00645 { 00646 mhdf_setFail( status, "H5Gopen(\"%s\") failed", TAG_GROUP ); 00647 return NULL; 00648 } 00649 00650 /* Get number of objects in tags group */ 00651 00652 if( H5Gget_num_objs( group_id, &count ) < 0 ) 00653 { 00654 mhdf_setFail( status, "Internal failure calling H5Gget_num_objs." ); 00655 H5Gclose( group_id ); 00656 return NULL; 00657 } 00658 00659 /* No tags? */ 00660 00661 *num_names_out = (int)count; 00662 if( count == 0 ) 00663 { 00664 H5Gclose( group_id ); 00665 mhdf_setOkay( status ); 00666 return NULL; 00667 } 00668 00669 /* Allocate string array */ 00670 00671 result = (char**)mhdf_malloc( sizeof( char* ) * count, status ); 00672 if( NULL == result ) 00673 { 00674 H5Gclose( group_id ); 00675 return NULL; 00676 } 00677 00678 /* Get names */ 00679 00680 for( idx = 0; idx < count; ++idx ) 00681 { 00682 size = H5Gget_objname_by_idx( group_id, idx, NULL, 0 ); 00683 if( size < 1 || NULL == ( name = (char*)mhdf_malloc( size + 1, status ) ) ) 00684 { 00685 while( ( --idx ) > 0 ) 00686 free( result[ idx ] ); 00687 free( result ); 00688 H5Gclose( group_id ); 00689 mhdf_setFail( status, "Internal failure calling H5Gget_objname_by_idx." ); 00690 return NULL; 00691 } 00692 00693 H5Gget_objname_by_idx( group_id, idx, name, size + 1 ); 00694 if( !mhdf_path_to_name( name, name ) ) 00695 { 00696 mhdf_setFail( status, "Invalid character string in internal file path: \"%s\"\n", name ); 00697 return NULL; 00698 } 00699 result[ idx ] = name; 00700 } 00701 00702 H5Gclose( group_id ); 00703 mhdf_setOkay( status ); 00704 API_END; 00705 return result; 00706 } 00707 00708 static int get_attrib_array_length_handle( hid_t attrib_id ) 00709 { 00710 hid_t type_id; 00711 int rank; 00712 hsize_t dims[ H5S_MAX_RANK ]; 00713 int perm[ H5S_MAX_RANK ]; 00714 00715 type_id = H5Aget_type( attrib_id ); 00716 switch( H5Tget_class( type_id ) ) 00717 { 00718 case H5T_NO_CLASS: 00719 dims[ 0 ] = -1; 00720 break; 00721 case H5T_OPAQUE: 00722 dims[ 0 ] = H5Tget_size( type_id ); 00723 break; 00724 case H5T_ARRAY: 00725 #if defined( H5Tget_array_dims_vers ) && H5Tget_array_dims_vers > 1 00726 (void)perm; /* suppress warning */ 00727 rank = H5Tget_array_dims2( type_id, dims ); 00728 #else 00729 rank = H5Tget_array_dims( type_id, dims, perm ); 00730 #endif 00731 if( rank == 1 ) 00732 break; 00733 else 00734 return -1; 00735 default: 00736 dims[ 0 ] = 1; 00737 break; 00738 } 00739 00740 H5Tclose( type_id ); 00741 return dims[ 0 ]; 00742 } 00743 00744 /* 00745 static int get_attrib_array_length_index( hid_t object_id, unsigned int index ) 00746 { 00747 hid_t attrib_id; 00748 int result; 00749 00750 attrib_id = H5Aopen_idx( object_id, index ); 00751 if (attrib_id < 0) 00752 return -1; 00753 00754 result = get_attrib_array_length_handle( attrib_id ); 00755 H5Aclose( attrib_id ); 00756 return result; 00757 } 00758 */ 00759 00760 static int get_attrib_array_length_name( hid_t file, const char* path ) 00761 { 00762 hid_t attrib_id; 00763 int result; 00764 00765 attrib_id = H5Aopen_name( file, path ); 00766 if( attrib_id < 0 ) return -1; 00767 00768 result = get_attrib_array_length_handle( attrib_id ); 00769 H5Aclose( attrib_id ); 00770 return result; 00771 } 00772 00773 void mhdf_getTagInfo( mhdf_FileHandle file_handle, const char* tag_name, enum mhdf_TagDataType* class_out, 00774 int* size_out, int* tstt_storage_out, int* have_default_out, int* have_global_out, 00775 int* have_sparse_out, mhdf_Status* status ) 00776 { 00777 hid_t tag_id, type_id, super_id; 00778 int i, rval, is_handle; 00779 hsize_t size, sup_size; 00780 unsigned int idx; 00781 int rank, var_data; 00782 hsize_t dims[ H5S_MAX_RANK ]; 00783 int perm[ H5S_MAX_RANK ]; 00784 H5T_class_t class_tmp; 00785 00786 API_BEGIN; 00787 00788 /* Validate input */ 00789 if( NULL == tag_name || NULL == class_out || NULL == size_out || NULL == tstt_storage_out || 00790 NULL == have_default_out || NULL == have_global_out || NULL == have_sparse_out ) 00791 { 00792 mhdf_setFail( status, "Invalid input." ); 00793 return; 00794 } 00795 00796 /* Get group for tag */ 00797 tag_id = get_tag( file_handle, tag_name, NULL, status ); 00798 if( tag_id < 0 ) return; 00799 00800 /* Check for sparse data */ 00801 rval = mhdf_is_in_group( tag_id, SPARSE_ENTITY_NAME, status ); 00802 if( rval < 0 ) 00803 { 00804 H5Gclose( tag_id ); 00805 return; 00806 } 00807 *have_sparse_out = rval ? 1 : 0; 00808 00809 /* Check for variable-length tag data */ 00810 rval = mhdf_find_attribute( tag_id, TAG_VARLEN_ATTRIB, &idx, status ); 00811 if( rval < 0 ) 00812 { 00813 H5Gclose( tag_id ); 00814 return; 00815 } 00816 var_data = rval ? 1 : 0; 00817 00818 /* Check if have default value for tag */ 00819 rval = mhdf_find_attribute( tag_id, TAG_DEFAULT_ATTRIB, &idx, status ); 00820 if( rval < 0 ) 00821 { 00822 H5Gclose( tag_id ); 00823 return; 00824 } 00825 if( !rval ) 00826 *have_default_out = 0; 00827 else if( !var_data ) 00828 *have_default_out = 1; 00829 else 00830 { 00831 /* *have_default_out = get_attrib_array_length_index( tag_id, index ); */ 00832 *have_default_out = get_attrib_array_length_name( tag_id, TAG_DEFAULT_ATTRIB ); 00833 if( *have_default_out < 0 ) 00834 { 00835 mhdf_setFail( status, "Error checking length of default value for tag: %s\n", tag_name ); 00836 H5Gclose( tag_id ); 00837 return; 00838 } 00839 } 00840 00841 /* Check if have global value for tag */ 00842 rval = mhdf_find_attribute( tag_id, TAG_GLOBAL_ATTRIB, &idx, status ); 00843 if( rval < 0 ) 00844 { 00845 H5Gclose( tag_id ); 00846 return; 00847 } 00848 if( !rval ) 00849 *have_global_out = 0; 00850 else if( !var_data ) 00851 *have_global_out = 1; 00852 else 00853 { 00854 /* *have_global_out = get_attrib_array_length_index( tag_id, index ); */ 00855 *have_global_out = get_attrib_array_length_name( tag_id, TAG_GLOBAL_ATTRIB ); 00856 if( *have_global_out < 0 ) 00857 { 00858 mhdf_setFail( status, "Error checking length of global value for tag: %s\n", tag_name ); 00859 H5Gclose( tag_id ); 00860 return; 00861 } 00862 } 00863 00864 /* Get TSTT tag class */ 00865 rval = mhdf_read_scalar_attrib( tag_id, TAG_TYPE_ATTRIB, H5T_NATIVE_INT, tstt_storage_out, status ); 00866 if( rval < 1 ) 00867 { 00868 H5Gclose( tag_id ); 00869 return; 00870 } 00871 00872 /* Check if tag is storing entity handles */ 00873 rval = mhdf_find_attribute( tag_id, TAG_HANDLE_TYPE_ATTRIB, &idx, status ); 00874 if( rval < 0 ) 00875 { 00876 H5Gclose( tag_id ); 00877 return; 00878 } 00879 is_handle = rval; 00880 00881 /* Get tag type */ 00882 #if defined( H5Topen_vers ) && H5Topen_vers > 1 00883 type_id = H5Topen2( tag_id, TAG_TYPE_NAME, H5P_DEFAULT ); 00884 #else 00885 type_id = H5Topen( tag_id, TAG_TYPE_NAME ); 00886 #endif 00887 if( type_id < 0 ) 00888 { 00889 H5Gclose( tag_id ); 00890 mhdf_setFail( status, "Failed to get type object for tag \"%s\".", tag_name ); 00891 return; 00892 } 00893 00894 class_tmp = H5Tget_class( type_id ); 00895 if( class_tmp < 0 ) 00896 { 00897 mhdf_setFail( status, "H5Tget_class failed." ); 00898 H5Gclose( tag_id ); 00899 H5Tclose( type_id ); 00900 return; 00901 } 00902 00903 size = H5Tget_size( type_id ); 00904 if( size <= 0 ) 00905 { 00906 mhdf_setFail( status, "H5Tget_size failed." ); 00907 H5Gclose( tag_id ); 00908 H5Tclose( type_id ); 00909 return; 00910 } 00911 00912 switch( class_tmp ) 00913 { 00914 case H5T_INTEGER: 00915 *class_out = ( size == 1 ) ? mhdf_BOOLEAN : mhdf_INTEGER; 00916 *size_out = 1; 00917 break; 00918 00919 case H5T_FLOAT: 00920 *class_out = mhdf_FLOAT; 00921 *size_out = 1; 00922 break; 00923 00924 case H5T_BITFIELD: 00925 *class_out = mhdf_BITFIELD; 00926 *size_out = H5Tget_precision( type_id ); 00927 if( *size_out <= 0 ) 00928 { 00929 mhdf_setFail( status, "H5Tget_precision failed." ); 00930 H5Gclose( tag_id ); 00931 H5Tclose( type_id ); 00932 return; 00933 } 00934 break; 00935 00936 default: 00937 case H5T_OPAQUE: 00938 *class_out = mhdf_OPAQUE; 00939 *size_out = size; 00940 break; 00941 00942 case H5T_ARRAY: 00943 00944 #if defined( H5Tget_array_dims_vers ) && H5Tget_array_dims_vers > 1 00945 (void)perm; /* suppress warning */ 00946 rank = H5Tget_array_dims2( type_id, dims ); 00947 #else 00948 rank = H5Tget_array_dims( type_id, dims, perm ); 00949 #endif 00950 if( rank <= 0 ) 00951 { 00952 mhdf_setFail( status, "H5Tget_size failed." ); 00953 H5Gclose( tag_id ); 00954 H5Tclose( type_id ); 00955 return; 00956 } 00957 for( i = 1; i < rank; ++i ) 00958 dims[ 0 ] *= dims[ i ]; 00959 00960 super_id = H5Tget_super( type_id ); 00961 if( super_id < 0 ) 00962 { 00963 mhdf_setFail( status, "H5Tget_super failed" ); 00964 H5Gclose( tag_id ); 00965 H5Tclose( type_id ); 00966 return; 00967 } 00968 00969 class_tmp = H5Tget_class( super_id ); 00970 if( class_tmp < 0 ) 00971 { 00972 mhdf_setFail( status, "H5Tget_class failed." ); 00973 H5Gclose( tag_id ); 00974 H5Tclose( type_id ); 00975 H5Tclose( super_id ); 00976 return; 00977 } 00978 00979 sup_size = H5Tget_size( super_id ); 00980 H5Tclose( super_id ); 00981 if( sup_size <= 0 ) 00982 { 00983 mhdf_setFail( status, "H5Tget_size failed." ); 00984 H5Gclose( tag_id ); 00985 H5Tclose( type_id ); 00986 return; 00987 } 00988 00989 switch( class_tmp ) 00990 { 00991 case H5T_INTEGER: 00992 *class_out = ( sup_size == 1 ) ? mhdf_BOOLEAN : mhdf_INTEGER; 00993 *size_out = dims[ 0 ]; 00994 break; 00995 00996 case H5T_FLOAT: 00997 *class_out = mhdf_FLOAT; 00998 *size_out = dims[ 0 ]; 00999 break; 01000 01001 default: 01002 *class_out = mhdf_OPAQUE; 01003 *size_out = size; 01004 break; 01005 } 01006 01007 break; 01008 } 01009 H5Tclose( type_id ); 01010 H5Gclose( tag_id ); 01011 01012 if( is_handle ) 01013 { 01014 if( *class_out != mhdf_INTEGER ) 01015 { 01016 mhdf_setFail( status, "Non-integer tag marked as handle type." ); 01017 return; 01018 } 01019 *class_out = mhdf_ENTITY_ID; 01020 } 01021 01022 if( var_data ) 01023 { 01024 if( *size_out != 1 || *class_out == mhdf_BITFIELD ) 01025 { 01026 mhdf_setFail( status, "Invalid or unexpected variable-length tag data" ); 01027 return; 01028 } 01029 *size_out = -1; 01030 } 01031 01032 mhdf_setOkay( status ); 01033 API_END; 01034 } 01035 01036 static int read_tag_attrib_data( hid_t tag_id, const char* attrib_name, hid_t type_id, void* data, int is_var_len, 01037 mhdf_Status* status ) 01038 { 01039 int rval, ilen; 01040 unsigned idx; 01041 hid_t read_type = type_id; 01042 hsize_t len; 01043 01044 /* Check if tag has attribute */ 01045 rval = mhdf_find_attribute( tag_id, attrib_name, &idx, status ); 01046 if( rval < 0 ) 01047 return 0; 01048 else if( 0 == rval ) 01049 return 1; 01050 01051 if( NULL == data ) 01052 { 01053 mhdf_setFail( status, "Invalid input." ); 01054 return 0; 01055 } 01056 01057 if( is_var_len ) 01058 { 01059 /* len = get_attrib_array_length_index(tag_id, index); */ 01060 ilen = get_attrib_array_length_name( tag_id, attrib_name ); 01061 if( ilen < 0 ) 01062 { 01063 mhdf_setFail( status, "Failed to read length of default/mesh value for tag" ); 01064 return 0; 01065 } 01066 len = ilen; 01067 01068 /* caller passes type_id == 0 for OPAQUE */ 01069 if( 0 == type_id ) 01070 read_type = H5Tcreate( H5T_OPAQUE, len ); 01071 else 01072 { 01073 #if defined( H5Tarray_create_vers ) && H5Tarray_create_vers > 1 01074 read_type = H5Tarray_create2( type_id, 1, &len ); 01075 #else 01076 read_type = H5Tarray_create( type_id, 1, &len, 0 ); 01077 #endif 01078 } 01079 if( read_type < 0 ) 01080 { 01081 mhdf_setFail( status, "Failed to read mesh/default value for tag" ); 01082 return 0; 01083 } 01084 } 01085 01086 rval = mhdf_read_scalar_attrib( tag_id, attrib_name, read_type, data, status ); 01087 if( is_var_len ) H5Tclose( read_type ); 01088 01089 return rval; 01090 } 01091 01092 void mhdf_getTagValues( mhdf_FileHandle file_handle, const char* tag_name, hid_t output_data_type, void* default_value, 01093 void* global_value, mhdf_Status* status ) 01094 { 01095 hid_t tag_id; 01096 int rval, var_data; 01097 unsigned int idx; 01098 API_BEGIN; 01099 01100 /* check args */ 01101 if( NULL == tag_name || !*tag_name ) 01102 { 01103 mhdf_setFail( status, "Invalid input." ); 01104 return; 01105 } 01106 01107 /* Get the tag group */ 01108 tag_id = get_tag( file_handle, tag_name, NULL, status ); 01109 if( tag_id < 0 ) return; 01110 01111 /* Check for variable-length tag data */ 01112 rval = mhdf_find_attribute( tag_id, TAG_VARLEN_ATTRIB, &idx, status ); 01113 if( rval < 0 ) 01114 { 01115 H5Gclose( tag_id ); 01116 return; 01117 } 01118 var_data = rval ? 1 : 0; 01119 01120 /* Read default value if present */ 01121 rval = read_tag_attrib_data( tag_id, TAG_DEFAULT_ATTRIB, output_data_type, default_value, var_data, status ); 01122 if( !rval ) 01123 { 01124 H5Gclose( tag_id ); 01125 return; 01126 } 01127 01128 /* Read mesh value if present */ 01129 rval = read_tag_attrib_data( tag_id, TAG_GLOBAL_ATTRIB, output_data_type, global_value, var_data, status ); 01130 if( !rval ) 01131 { 01132 H5Gclose( tag_id ); 01133 return; 01134 } 01135 01136 H5Gclose( tag_id ); 01137 mhdf_setOkay( status ); 01138 API_END; 01139 } 01140 01141 int mhdf_haveDenseTag( mhdf_FileHandle file_handle, const char* tag_name, const char* type_handle, mhdf_Status* status ) 01142 { 01143 char* path; 01144 hid_t elem_id, group_id; 01145 FileHandle* file_ptr; 01146 int rval = 0; 01147 API_BEGIN; 01148 01149 file_ptr = (FileHandle*)file_handle; 01150 if( !mhdf_check_valid_file( file_ptr, status ) ) return -1; 01151 01152 if( type_handle == mhdf_node_type_handle( ) ) 01153 { 01154 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1 01155 elem_id = H5Gopen2( file_ptr->hdf_handle, NODE_GROUP, H5P_DEFAULT ); 01156 #else 01157 elem_id = H5Gopen( file_ptr->hdf_handle, NODE_GROUP ); 01158 #endif 01159 if( elem_id < 0 ) mhdf_setFail( status, "Could not open node group." ); 01160 } 01161 else if( type_handle == mhdf_set_type_handle( ) ) 01162 { 01163 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1 01164 elem_id = H5Gopen2( file_ptr->hdf_handle, SET_GROUP, H5P_DEFAULT ); 01165 #else 01166 elem_id = H5Gopen( file_ptr->hdf_handle, SET_GROUP ); 01167 #endif 01168 if( elem_id < 0 ) mhdf_setFail( status, "Could not open set group." ); 01169 } 01170 else 01171 { 01172 elem_id = mhdf_elem_group_from_handle( file_ptr, type_handle, status ); 01173 } 01174 if( elem_id < 0 ) return -1; 01175 01176 rval = mhdf_is_in_group( elem_id, TAG_GROUP_NAME, status ); 01177 if( rval < 0 ) 01178 { 01179 H5Gclose( elem_id ); 01180 return -1; 01181 } 01182 else if( rval == 0 ) 01183 { 01184 H5Gclose( elem_id ); 01185 mhdf_setOkay( status ); 01186 return 0; 01187 } 01188 01189 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1 01190 group_id = H5Gopen2( elem_id, DENSE_TAG_SUBGROUP, H5P_DEFAULT ); 01191 #else 01192 group_id = H5Gopen( elem_id, DENSE_TAG_SUBGROUP ); 01193 #endif 01194 H5Gclose( elem_id ); 01195 if( group_id < 0 ) 01196 { 01197 mhdf_setFail( status, "Could not open tag subgroup." ); 01198 return -1; 01199 } 01200 01201 path = mhdf_name_to_path_copy( tag_name, status ); 01202 if( NULL == path ) 01203 { 01204 H5Gclose( group_id ); 01205 return -1; 01206 } 01207 01208 rval = mhdf_is_in_group( group_id, path, status ); 01209 H5Gclose( group_id ); 01210 free( path ); 01211 01212 if( rval >= 0 ) { mhdf_setOkay( status ); } 01213 01214 API_END; 01215 return rval; 01216 } 01217 01218 hid_t mhdf_createDenseTagData( mhdf_FileHandle file_handle, const char* tag_name, const char* type_handle, 01219 long num_values, mhdf_Status* status ) 01220 { 01221 char* path; 01222 hid_t elem_id, data_id, type_id; 01223 FileHandle* file_ptr; 01224 size_t name_len, path_len, dir_len; 01225 hsize_t size; 01226 API_BEGIN; 01227 01228 file_ptr = (FileHandle*)file_handle; 01229 if( !mhdf_check_valid_file( file_ptr, status ) ) return -1; 01230 01231 if( type_handle == mhdf_node_type_handle( ) ) 01232 { 01233 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1 01234 elem_id = H5Gopen2( file_ptr->hdf_handle, NODE_GROUP, H5P_DEFAULT ); 01235 #else 01236 elem_id = H5Gopen( file_ptr->hdf_handle, NODE_GROUP ); 01237 #endif 01238 if( elem_id < 0 ) mhdf_setFail( status, "Could not open node group." ); 01239 } 01240 else if( type_handle == mhdf_set_type_handle( ) ) 01241 { 01242 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1 01243 elem_id = H5Gopen2( file_ptr->hdf_handle, SET_GROUP, H5P_DEFAULT ); 01244 #else 01245 elem_id = H5Gopen( file_ptr->hdf_handle, SET_GROUP ); 01246 #endif 01247 if( elem_id < 0 ) mhdf_setFail( status, "Could not open set group." ); 01248 } 01249 else 01250 { 01251 elem_id = mhdf_elem_group_from_handle( file_ptr, type_handle, status ); 01252 } 01253 if( elem_id < 0 ) return -1; 01254 01255 dir_len = strlen( DENSE_TAG_SUBGROUP ); 01256 name_len = mhdf_name_to_path( tag_name, NULL, 0 ); 01257 path_len = dir_len + name_len + 1; 01258 path = (char*)mhdf_malloc( path_len, status ); 01259 if( NULL == path ) 01260 { 01261 H5Gclose( elem_id ); 01262 return -1; 01263 } 01264 strcpy( path, DENSE_TAG_SUBGROUP ); 01265 mhdf_name_to_path( tag_name, path + dir_len, name_len + 1 ); 01266 01267 type_id = get_tag_type( file_ptr, path + dir_len, status ); 01268 if( type_id < 0 ) 01269 { 01270 H5Gclose( elem_id ); 01271 return -1; 01272 } 01273 01274 size = (hsize_t)num_values; 01275 data_id = mhdf_create_table( elem_id, path, type_id, 1, &size, status ); 01276 free( path ); 01277 H5Gclose( elem_id ); 01278 H5Tclose( type_id ); 01279 01280 if( data_id > 0 ) mhdf_setOkay( status ); 01281 01282 API_END_H( 1 ); 01283 return data_id; 01284 } 01285 01286 hid_t mhdf_openDenseTagData( mhdf_FileHandle file_handle, const char* tag_name, const char* type_handle, 01287 long* num_values_out, mhdf_Status* status ) 01288 { 01289 char* path; 01290 hid_t elem_id, data_id; 01291 FileHandle* file_ptr; 01292 size_t name_len, path_len, dir_len; 01293 hsize_t size; 01294 API_BEGIN; 01295 01296 file_ptr = (FileHandle*)file_handle; 01297 if( !mhdf_check_valid_file( file_ptr, status ) ) return -1; 01298 01299 if( type_handle == mhdf_node_type_handle( ) ) 01300 { 01301 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1 01302 elem_id = H5Gopen2( file_ptr->hdf_handle, NODE_GROUP, H5P_DEFAULT ); 01303 #else 01304 elem_id = H5Gopen( file_ptr->hdf_handle, NODE_GROUP ); 01305 #endif 01306 if( elem_id < 0 ) mhdf_setFail( status, "Could not open node group." ); 01307 } 01308 else if( type_handle == mhdf_set_type_handle( ) ) 01309 { 01310 #if defined( H5Gopen_vers ) && H5Gopen_vers > 1 01311 elem_id = H5Gopen2( file_ptr->hdf_handle, SET_GROUP, H5P_DEFAULT ); 01312 #else 01313 elem_id = H5Gopen( file_ptr->hdf_handle, SET_GROUP ); 01314 #endif 01315 if( elem_id < 0 ) mhdf_setFail( status, "Could not open set group." ); 01316 } 01317 else 01318 { 01319 elem_id = mhdf_elem_group_from_handle( file_ptr, type_handle, status ); 01320 } 01321 if( elem_id < 0 ) return -1; 01322 01323 dir_len = strlen( DENSE_TAG_SUBGROUP ); 01324 name_len = mhdf_name_to_path( tag_name, NULL, 0 ); 01325 path_len = dir_len + name_len + 1; 01326 path = (char*)mhdf_malloc( path_len, status ); 01327 if( NULL == path ) 01328 { 01329 H5Gclose( elem_id ); 01330 return -1; 01331 } 01332 strcpy( path, DENSE_TAG_SUBGROUP ); 01333 mhdf_name_to_path( tag_name, path + dir_len, name_len + 1 ); 01334 01335 data_id = mhdf_open_table( elem_id, path, 1, &size, status ); 01336 free( path ); 01337 H5Gclose( elem_id ); 01338 *num_values_out = (long)size; 01339 01340 if( data_id >= 0 ) mhdf_setOkay( status ); 01341 01342 API_END_H( 1 ); 01343 return data_id; 01344 } 01345 01346 void mhdf_createSparseTagData( mhdf_FileHandle file_handle, const char* tag_name, long num_values, 01347 hid_t handles_out[ 2 ], mhdf_Status* status ) 01348 { 01349 hid_t tag_id, index_id, data_id, type_id, id_type; 01350 hsize_t count = (hsize_t)num_values; 01351 API_BEGIN; 01352 01353 tag_id = get_tag( file_handle, tag_name, &id_type, status ); 01354 if( tag_id < 0 ) return; 01355 01356 #if defined( H5Topen_vers ) && H5Topen_vers > 1 01357 type_id = H5Topen2( tag_id, TAG_TYPE_NAME, H5P_DEFAULT ); 01358 #else 01359 type_id = H5Topen( tag_id, TAG_TYPE_NAME ); 01360 #endif 01361 if( type_id < 0 ) 01362 { 01363 H5Gclose( tag_id ); 01364 mhdf_setFail( status, "Failed to get type object for tag \"%s\".", tag_name ); 01365 return; 01366 } 01367 01368 index_id = mhdf_create_table( tag_id, SPARSE_ENTITY_NAME, id_type, 1, &count, status ); 01369 if( index_id < 0 ) 01370 { 01371 H5Gclose( tag_id ); 01372 H5Tclose( type_id ); 01373 return; 01374 } 01375 01376 data_id = mhdf_create_table( tag_id, SPARSE_VALUES_NAME, type_id, 1, &count, status ); 01377 H5Tclose( type_id ); 01378 H5Gclose( tag_id ); 01379 if( data_id < 0 ) 01380 { 01381 H5Dclose( index_id ); 01382 return; 01383 } 01384 01385 handles_out[ 0 ] = index_id; 01386 handles_out[ 1 ] = data_id; 01387 mhdf_setOkay( status ); 01388 API_END_H( 2 ); 01389 } 01390 01391 void mhdf_createVarLenTagData( mhdf_FileHandle file_handle, const char* tag_name, long num_entities, long num_values, 01392 hid_t handles_out[ 3 ], mhdf_Status* status ) 01393 { 01394 hid_t tag_id, index_id, data_id, type_id, offset_id, id_type; 01395 hsize_t count = (hsize_t)num_entities; 01396 API_BEGIN; 01397 01398 tag_id = get_tag( file_handle, tag_name, &id_type, status ); 01399 if( tag_id < 0 ) return; 01400 01401 #if defined( H5Topen_vers ) && H5Topen_vers > 1 01402 type_id = H5Topen2( tag_id, TAG_TYPE_NAME, H5P_DEFAULT ); 01403 #else 01404 type_id = H5Topen( tag_id, TAG_TYPE_NAME ); 01405 #endif 01406 if( type_id < 0 ) 01407 { 01408 H5Gclose( tag_id ); 01409 mhdf_setFail( status, "Failed to get type object for tag \"%s\".", tag_name ); 01410 return; 01411 } 01412 01413 index_id = mhdf_create_table( tag_id, SPARSE_ENTITY_NAME, id_type, 1, &count, status ); 01414 if( index_id < 0 ) 01415 { 01416 H5Gclose( tag_id ); 01417 H5Tclose( type_id ); 01418 return; 01419 } 01420 01421 offset_id = mhdf_create_table( tag_id, TAG_VAR_INDICES, MHDF_INDEX_TYPE, 1, &count, status ); 01422 if( index_id < 0 ) 01423 { 01424 H5Dclose( offset_id ); 01425 H5Gclose( tag_id ); 01426 H5Tclose( type_id ); 01427 return; 01428 } 01429 01430 count = (hsize_t)num_values; 01431 data_id = mhdf_create_table( tag_id, SPARSE_VALUES_NAME, type_id, 1, &count, status ); 01432 H5Tclose( type_id ); 01433 H5Gclose( tag_id ); 01434 if( data_id < 0 ) 01435 { 01436 H5Dclose( offset_id ); 01437 H5Dclose( index_id ); 01438 return; 01439 } 01440 01441 handles_out[ 0 ] = index_id; 01442 handles_out[ 1 ] = data_id; 01443 handles_out[ 2 ] = offset_id; 01444 mhdf_setOkay( status ); 01445 API_END_H( 3 ); 01446 } 01447 01448 void mhdf_openSparseTagData( mhdf_FileHandle file_handle, const char* tag_name, long* num_entity_out, 01449 long* num_values_out, hid_t handles_out[ 3 ], mhdf_Status* status ) 01450 { 01451 hid_t tag_id, index_id, data_id, offset_id = -1; 01452 hsize_t num_ent, data_size, num_data; 01453 int rval; 01454 unsigned idx; 01455 API_BEGIN; 01456 01457 tag_id = get_tag( file_handle, tag_name, NULL, status ); 01458 if( tag_id < 0 ) return; 01459 01460 index_id = mhdf_open_table( tag_id, SPARSE_ENTITY_NAME, 1, &num_ent, status ); 01461 if( index_id < 0 ) 01462 { 01463 H5Gclose( tag_id ); 01464 return; 01465 } 01466 01467 data_id = mhdf_open_table( tag_id, SPARSE_VALUES_NAME, 1, &data_size, status ); 01468 if( data_id < 0 ) 01469 { 01470 H5Gclose( tag_id ); 01471 H5Dclose( index_id ); 01472 return; 01473 } 01474 01475 /* check if tag is variable-lentgth */ 01476 rval = mhdf_find_attribute( tag_id, TAG_VARLEN_ATTRIB, &idx, status ); 01477 if( rval < 0 ) 01478 { 01479 H5Gclose( tag_id ); 01480 H5Dclose( index_id ); 01481 H5Dclose( data_id ); 01482 return; 01483 } 01484 01485 /* If variable length... */ 01486 if( rval ) 01487 { 01488 offset_id = mhdf_open_table( tag_id, TAG_VAR_INDICES, 1, &num_data, status ); 01489 if( offset_id < 0 ) 01490 { 01491 H5Gclose( tag_id ); 01492 H5Dclose( index_id ); 01493 H5Dclose( data_id ); 01494 return; 01495 } 01496 } 01497 /* Otherwise the number of values is the same as the size of the data table */ 01498 else 01499 { 01500 num_data = data_size; 01501 } 01502 01503 H5Gclose( tag_id ); 01504 if( num_ent != num_data ) 01505 { 01506 mhdf_setFail( status, "Data length mismatch for sparse tag data -- invalid file." ); 01507 if( offset_id >= 0 ) H5Dclose( offset_id ); 01508 H5Dclose( index_id ); 01509 H5Dclose( data_id ); 01510 return; 01511 } 01512 *num_entity_out = (long)num_ent; 01513 if( num_values_out ) *num_values_out = (long)data_size; 01514 01515 handles_out[ 0 ] = index_id; 01516 handles_out[ 1 ] = data_id; 01517 if( offset_id >= 0 ) handles_out[ 2 ] = offset_id; 01518 mhdf_setOkay( status ); 01519 API_END_H( 2 ); 01520 } 01521 01522 void mhdf_writeSparseTagEntities( hid_t table_id, long offset, long count, hid_t int_type, const void* id_list, 01523 mhdf_Status* status ) 01524 { 01525 API_BEGIN; 01526 mhdf_write_data( table_id, offset, count, int_type, id_list, H5P_DEFAULT, status ); 01527 API_END; 01528 } 01529 void mhdf_writeSparseTagEntitiesWithOpt( hid_t table_id, long offset, long count, hid_t int_type, const void* id_list, 01530 hid_t io_prop, mhdf_Status* status ) 01531 { 01532 API_BEGIN; 01533 mhdf_write_data( table_id, offset, count, int_type, id_list, io_prop, status ); 01534 API_END; 01535 } 01536 01537 void mhdf_writeTagValues( hid_t table_id, long offset, long count, hid_t tag_type, const void* tag_data, 01538 mhdf_Status* status ) 01539 { 01540 mhdf_writeTagValuesWithOpt( table_id, offset, count, tag_type, tag_data, H5P_DEFAULT, status ); 01541 } 01542 01543 void mhdf_writeTagValuesWithOpt( hid_t table_id, long offset, long count, hid_t tag_type, const void* tag_data, 01544 hid_t io_prop, mhdf_Status* status ) 01545 { 01546 API_BEGIN; 01547 mhdf_write_data( table_id, offset, count, tag_type, tag_data, io_prop, status ); 01548 API_END; 01549 } 01550 01551 void mhdf_writeSparseTagIndices( hid_t table_id, long offset, long count, hid_t int_type, const void* indices, 01552 mhdf_Status* status ) 01553 { 01554 API_BEGIN; 01555 mhdf_write_data( table_id, offset, count, int_type, indices, H5P_DEFAULT, status ); 01556 API_END; 01557 } 01558 void mhdf_writeSparseTagIndicesWithOpt( hid_t table_id, long offset, long count, hid_t int_type, const void* indices, 01559 hid_t io_prop, mhdf_Status* status ) 01560 { 01561 API_BEGIN; 01562 mhdf_write_data( table_id, offset, count, int_type, indices, io_prop, status ); 01563 API_END; 01564 } 01565 01566 void mhdf_readSparseTagEntities( hid_t table_id, long offset, long count, hid_t int_type, void* id_list, 01567 mhdf_Status* status ) 01568 { 01569 API_BEGIN; 01570 mhdf_read_data( table_id, offset, count, int_type, id_list, H5P_DEFAULT, status ); 01571 API_END; 01572 } 01573 void mhdf_readSparseTagEntitiesWithOpt( hid_t table_id, long offset, long count, hid_t int_type, void* id_list, 01574 hid_t io_prop, mhdf_Status* status ) 01575 { 01576 API_BEGIN; 01577 mhdf_read_data( table_id, offset, count, int_type, id_list, io_prop, status ); 01578 API_END; 01579 } 01580 01581 void mhdf_readTagValues( hid_t table_id, long offset, long count, hid_t tag_type, void* tag_data, mhdf_Status* status ) 01582 { 01583 mhdf_readTagValuesWithOpt( table_id, offset, count, tag_type, tag_data, H5P_DEFAULT, status ); 01584 } 01585 void mhdf_readTagValuesWithOpt( hid_t table_id, long offset, long count, hid_t tag_type, void* tag_data, hid_t io_prop, 01586 mhdf_Status* status ) 01587 { 01588 API_BEGIN; 01589 mhdf_read_data( table_id, offset, count, tag_type, tag_data, io_prop, status ); 01590 API_END; 01591 } 01592 01593 void mhdf_readSparseTagIndices( hid_t table_id, long offset, long count, hid_t int_type, void* indices, 01594 mhdf_Status* status ) 01595 { 01596 API_BEGIN; 01597 mhdf_read_data( table_id, offset, count, int_type, indices, H5P_DEFAULT, status ); 01598 API_END; 01599 } 01600 void mhdf_readSparseTagIndicesWithOpt( hid_t table_id, long offset, long count, hid_t int_type, void* indices, 01601 hid_t io_prop, mhdf_Status* status ) 01602 { 01603 API_BEGIN; 01604 mhdf_read_data( table_id, offset, count, int_type, indices, io_prop, status ); 01605 API_END; 01606 }