Loading [MathJax]/extensions/tex2jax.js
Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
file-desc.c
Go to the documentation of this file.
1 #include "mhdf.h" 2 #include "util.h" 3 #include "status.h" 4 #include <assert.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include <H5Tpublic.h> 8 #include <H5Dpublic.h> 9 #include <H5Ppublic.h> 10  11 static struct mhdf_FileDesc* alloc_file_desc( mhdf_Status* status ); 12 static void* realloc_data( struct mhdf_FileDesc** data, size_t append_bytes, mhdf_Status* status, int alignment ); 13 static char buffer[512]; 14  15 static struct mhdf_FileDesc* alloc_file_desc( mhdf_Status* status ) 16 { 17  struct mhdf_FileDesc* result; 18  /* allocate a little short of a page */ 19  result = (struct mhdf_FileDesc*)mhdf_malloc( 4000, status ); 20  if( mhdf_isError( status ) ) return 0; 21  22  memset( result, 0, sizeof( struct mhdf_FileDesc ) ); 23  result->total_size = 4000; 24  result->offset = ( (unsigned char*)result ) + sizeof( struct mhdf_FileDesc ); 25  return result; 26 } 27  28 static void* realloc_data( struct mhdf_FileDesc** data, size_t append_bytes, mhdf_Status* status, int alignment ) 29 { 30  void* result_ptr; 31  struct mhdf_FileDesc* const input_ptr = *data; 32  unsigned char* mem_ptr = (unsigned char*)input_ptr; 33  34  size_t new_size, occupied_size = input_ptr->offset - mem_ptr; 35  36  size_t append_bytes_padded = append_bytes + alignment - 1; 37  /* if the end of the allocated space is before the end of the required space */ 38  if( mem_ptr + input_ptr->total_size < input_ptr->offset + append_bytes_padded ) 39  { 40  if( append_bytes_padded < input_ptr->total_size ) 41  new_size = 2 * input_ptr->total_size; 42  else 43  new_size = input_ptr->total_size + append_bytes_padded; 44  *data = (struct mhdf_FileDesc*)mhdf_realloc( *data, new_size, status ); 45  if( mhdf_isError( status ) ) return 0; 46  47  /* if realloc moved us to a different location in memory, 48  * we need to update all of the internal pointers to 49  * new locations relative to the start of the struct */ 50  if( *data != input_ptr ) 51  { 52  mhdf_fixFileDesc( *data, input_ptr ); 53  mem_ptr = (unsigned char*)( *data ); 54  ( *data )->offset = mem_ptr + occupied_size; 55  } 56  ( *data )->total_size = new_size; 57  } 58  59  result_ptr = ( *data )->offset; 60  /* need to make this return pointer aligned */ 61  uintptr_t addr = (uintptr_t)( ( *data )->offset ); 62  int pad = addr % alignment; 63  if( pad > 0 ) 64  { 65  ( *data )->offset += ( alignment - pad ); 66  result_ptr = ( *data )->offset; 67  } 68  /*printf("new address %p \n", result_ptr);*/ 69  ( *data )->offset += append_bytes; 70  return result_ptr; 71 } 72  73 #define FIX_OFFSET( TYPE, FIELD ) \ 74  if( copy_ptr->FIELD != NULL ) \ 75  copy_ptr->FIELD = (TYPE)( ( (char*)( copy_ptr->FIELD ) - (char*)orig_addr ) + (char*)copy_ptr ) 76  77 void mhdf_fixFileDesc( struct mhdf_FileDesc* copy_ptr, const struct mhdf_FileDesc* orig_addr ) 78 { 79  int i; 80  81  API_BEGIN; 82  FIX_OFFSET( int*, nodes.dense_tag_indices ); 83  FIX_OFFSET( int*, sets.dense_tag_indices ); 84  FIX_OFFSET( struct mhdf_ElemDesc*, elems ); 85  FIX_OFFSET( struct mhdf_TagDesc*, tags ); 86  87  FIX_OFFSET( int*, numEntSets ); 88  FIX_OFFSET( int**, defTagsEntSets ); 89  FIX_OFFSET( int**, defTagsVals ); 90  91  for( i = 0; i < 5; i++ ) 92  { 93  if( copy_ptr->defTagsEntSets ) FIX_OFFSET( int*, defTagsEntSets[i] ); 94  if( copy_ptr->defTagsVals ) FIX_OFFSET( int*, defTagsVals[i] ); 95  } 96  97  if( copy_ptr->elems != NULL ) 98  { 99  for( i = 0; i < copy_ptr->num_elem_desc; ++i ) 100  { 101  FIX_OFFSET( const char*, elems[i].handle ); 102  FIX_OFFSET( const char*, elems[i].type ); 103  FIX_OFFSET( int*, elems[i].desc.dense_tag_indices ); 104  } 105  } 106  107  if( copy_ptr->tags != NULL ) 108  { 109  for( i = 0; i < copy_ptr->num_tag_desc; ++i ) 110  { 111  FIX_OFFSET( const char*, tags[i].name ); 112  FIX_OFFSET( void*, tags[i].default_value ); 113  FIX_OFFSET( void*, tags[i].global_value ); 114  FIX_OFFSET( int*, tags[i].dense_elem_indices ); 115  } 116  } 117  API_END; 118 } 119  120 static struct mhdf_FileDesc* get_elem_desc( mhdf_FileHandle file_handle, 121  struct mhdf_FileDesc* result, 122  const char* elem_handle, 123  int idx, 124  mhdf_Status* status ) 125 { 126  hid_t id_pair[2]; 127  int poly; 128  void* ptr; 129  long junk; 130  131  ptr = realloc_data( &result, strlen( elem_handle ) + 1, status, sizeof( char ) ); 132  if( !ptr ) return NULL; 133  strcpy( ptr, elem_handle ); 134  result->elems[idx].handle = ptr; 135  136  mhdf_getElemTypeName( file_handle, elem_handle, buffer, sizeof( buffer ), status ); 137  if( mhdf_isError( status ) ) 138  { 139  free( result ); 140  return NULL; 141  } 142  143  ptr = realloc_data( &result, strlen( buffer ) + 1, status, sizeof( char ) ); 144  if( !ptr ) return NULL; 145  strcpy( ptr, buffer ); 146  result->elems[idx].type = ptr; 147  148  poly = mhdf_isPolyElement( file_handle, elem_handle, status ); 149  if( mhdf_isError( status ) ) 150  { 151  free( result ); 152  return NULL; 153  } 154  155  if( !poly ) 156  { 157  id_pair[0] = mhdf_openConnectivity( file_handle, elem_handle, &result->elems[idx].desc.vals_per_ent, 158  &result->elems[idx].desc.count, &result->elems[idx].desc.start_id, status ); 159  if( id_pair[0] < 0 ) 160  { 161  free( result ); 162  return NULL; 163  } 164  mhdf_closeData( file_handle, id_pair[0], status ); 165  } 166  else 167  { 168  result->elems[idx].desc.vals_per_ent = -1; 169  mhdf_openPolyConnectivity( file_handle, elem_handle, &result->elems[idx].desc.count, &junk, 170  &result->elems[idx].desc.start_id, id_pair, status ); 171  if( id_pair[0] < 0 ) 172  { 173  free( result ); 174  return NULL; 175  } 176  mhdf_closeData( file_handle, id_pair[0], status ); 177  mhdf_closeData( file_handle, id_pair[1], status ); 178  } 179  180  result->elems[idx].desc.dense_tag_indices = NULL; 181  result->elems[idx].desc.num_dense_tags = 0; 182  result->elems[idx].have_adj = mhdf_haveAdjacency( file_handle, result->elems[idx].handle, status ); 183  if( mhdf_isError( status ) ) 184  { 185  free( result ); 186  return 0; 187  } 188  189  return result; 190 } 191  192 static unsigned get_file_id_size( hid_t file_id_type, mhdf_Status* status ) 193 { 194  if( H5Tget_class( file_id_type ) != H5T_INTEGER ) 195  { 196  mhdf_setFail( status, "Invalid handle or type class for file ID type." ); 197  return 0; 198  } 199  200  return H5Tget_size( file_id_type ); 201 } 202  203 static struct mhdf_FileDesc* get_tag_desc( mhdf_FileHandle file_handle, 204  struct mhdf_FileDesc* result, 205  const char* name, 206  int idx, 207  hid_t type, 208  mhdf_Status* status ) 209 { 210  void* ptr; 211  int have_default, have_global; 212  int valsize, size, close_type = 0; 213  hsize_t array_len; 214  215  ptr = realloc_data( &result, strlen( name ) + 1, status, sizeof( char ) ); 216  if( NULL == ptr ) return NULL; 217  strcpy( ptr, name ); 218  result->tags[idx].name = ptr; 219  220  mhdf_getTagInfo( file_handle, name, &result->tags[idx].type, &result->tags[idx].size, &result->tags[idx].storage, 221  &have_default, &have_global, &result->tags[idx].have_sparse, status ); 222  if( mhdf_isError( status ) ) 223  { 224  free( result ); 225  return NULL; 226  } 227  228  /* For variable length tags, have_default and have_global will 229  contain the size of the respective values. For fixed-length 230  tags, they are either zero or one. Simplify later code by 231  making them contain the size for both cases. */ 232  valsize = result->tags[idx].size; 233  if( result->tags[idx].size >= 0 ) 234  { 235  if( have_default ) have_default = valsize; 236  if( have_global ) have_global = valsize; 237  } 238  239  result->tags[idx].default_value = NULL; 240  result->tags[idx].default_value_size = have_default; 241  result->tags[idx].global_value = NULL; 242  result->tags[idx].global_value_size = have_global; 243  244  switch( result->tags[idx].type ) 245  { 246  case mhdf_OPAQUE: 247  type = 0; 248  break; 249  case mhdf_BOOLEAN: 250  type = H5T_NATIVE_UCHAR; 251  break; 252  case mhdf_INTEGER: 253  type = H5T_NATIVE_INT; 254  have_default *= sizeof( int ); 255  have_global *= sizeof( int ); 256  valsize *= sizeof( int ); 257  break; 258  case mhdf_FLOAT: 259  type = H5T_NATIVE_DOUBLE; 260  have_default *= sizeof( double ); 261  have_global *= sizeof( double ); 262  valsize *= sizeof( double ); 263  break; 264  case mhdf_BITFIELD: 265  have_default = ( have_default + 7 ) / 8; 266  have_global = ( have_global + 7 ) / 8; 267  valsize = ( valsize + 7 ) / 8; 268  switch( valsize ) 269  { 270  case 1: 271  type = H5Tcopy( H5T_NATIVE_B8 ); 272  break; 273  case 2: 274  type = H5Tcopy( H5T_NATIVE_B16 ); 275  break; 276  case 3: 277  case 4: 278  valsize += 4 - valsize; // to avoid fallthrough warning 279  type = H5Tcopy( H5T_NATIVE_B32 ); 280  break; 281  case 5: 282  case 6: 283  case 7: 284  case 8: 285  valsize += 8 - valsize; // to avoid fallthrough warning 286  type = H5Tcopy( H5T_NATIVE_B64 ); 287  break; 288  default: 289  free( result ); 290  mhdf_setFail( status, "Cannot create a bit tag larger than 64-bits. %d bits requested.\n", 291  (int)valsize ); 292  return NULL; 293  } 294  close_type = 1; 295  break; 296  case mhdf_ENTITY_ID: 297  if( 0 == type ) type = H5T_NATIVE_ULONG; 298  size = get_file_id_size( type, status ); 299  if( !size ) 300  { 301  free( result ); 302  return NULL; 303  } 304  have_default *= size; 305  have_global *= size; 306  valsize *= size; 307  break; 308  default: 309  mhdf_setFail( status, "Unknown mhdf_TagDataType value (%d) for tag (\"%s\")", (int)result->tags[idx].type, 310  name ); 311  free( result ); 312  return NULL; 313  } 314  result->tags[idx].bytes = valsize; 315  316  if( result->tags[idx].type != mhdf_OPAQUE && result->tags[idx].type != mhdf_BITFIELD && result->tags[idx].size > 1 ) 317  { 318  close_type = 1; 319  array_len = result->tags[idx].size; 320 #if defined( H5Tarray_create_vers ) && H5Tarray_create_vers > 1 321  type = H5Tarray_create2( type, 1, &array_len ); 322 #else 323  type = H5Tarray_create( type, 1, &array_len, 0 ); 324 #endif 325  if( type < 0 ) 326  { 327  mhdf_setFail( status, "H5Tarray_create failed for tag (\"%s\")", name ); 328  free( result ); 329  return NULL; 330  } 331  } 332  333  if( have_default || have_global ) 334  { 335  if( have_default ) 336  { 337  ptr = realloc_data( &result, have_default, status, sizeof( int ) ); 338  if( NULL == ptr ) 339  { 340  if( close_type ) 341  { 342  H5Tclose( type ); 343  } 344  return NULL; 345  } 346  result->tags[idx].default_value = ptr; 347  } 348  if( have_global ) 349  { 350  ptr = realloc_data( &result, have_global, status, sizeof( int ) ); 351  if( NULL == ptr ) 352  { 353  if( close_type ) 354  { 355  H5Tclose( type ); 356  } 357  return NULL; 358  } 359  result->tags[idx].global_value = ptr; 360  } 361  mhdf_getTagValues( file_handle, name, type, result->tags[idx].default_value, result->tags[idx].global_value, 362  status ); 363  if( close_type ) 364  { 365  H5Tclose( type ); 366  } 367  if( mhdf_isError( status ) ) 368  { 369  free( result ); 370  return NULL; 371  } 372  } 373  374  return result; 375 } 376  377 static void free_string_list( char** list, int count ) 378 { 379  int i; 380  for( i = 0; i < count; ++i ) 381  free( list[i] ); 382  free( list ); 383 } 384  385 struct mhdf_FileDesc* mhdf_getFileSummary( mhdf_FileHandle file_handle, 386  hid_t file_id_type, 387  mhdf_Status* status, 388  int extraSetInfo ) 389 { 390  struct mhdf_FileDesc* result; 391  hid_t table_id; 392  int i, i1, numtags, j, k, size, *indices, have, num_tag_names = 0; 393  unsigned int ui; 394  void* ptr; 395  char **elem_handles = 0, **tag_names = 0; 396  unsigned char *array, *matrix; 397  const char* pname[5] = { "PARALLEL_PARTITION", "MATERIAL_SET", "NEUMANN_SET", "DIRICHLET_SET", "GEOM_DIMENSION" }; 398  399  long* id_list; 400  struct mhdf_TagDesc* tag_desc; 401  long int nval, junk; 402  hid_t table[3]; 403  hid_t data_type; 404  405  API_BEGIN; 406  407  mhdf_setOkay( status ); 408  result = alloc_file_desc( status ); 409  if( NULL == result ) return NULL; 410  411  /* get node info */ 412  have = mhdf_haveNodes( file_handle, status ); 413  if( mhdf_isError( status ) ) 414  { 415  free( result ); 416  return NULL; 417  } 418  if( have ) 419  { 420  table_id = mhdf_openNodeCoords( file_handle, &result->nodes.count, &result->nodes.vals_per_ent, 421  &result->nodes.start_id, status ); 422  if( table_id < 0 ) 423  { 424  free( result ); 425  return NULL; 426  } 427  mhdf_closeData( file_handle, table_id, status ); 428  } 429  else 430  { 431  result->nodes.count = 0; 432  result->nodes.vals_per_ent = 0; 433  result->nodes.start_id = 0; 434  } 435  436  /* get set info */ 437  result->sets.vals_per_ent = -1; 438  have = mhdf_haveSets( file_handle, &result->have_set_contents, &result->have_set_children, 439  &result->have_set_parents, status ); 440  if( mhdf_isError( status ) ) 441  { 442  free( result ); 443  return NULL; 444  } 445  if( have ) 446  { 447  table_id = mhdf_openSetMeta( file_handle, &result->sets.count, &result->sets.start_id, status ); 448  if( table_id < 0 ) 449  { 450  free( result ); 451  return NULL; 452  } 453  mhdf_closeData( file_handle, table_id, status ); 454  } 455  else 456  { 457  result->sets.count = 0; 458  result->sets.start_id = 0; 459  } 460  461  /* get element list */ 462  elem_handles = mhdf_getElemHandles( file_handle, &ui, status ); 463  if( elem_handles == NULL ) 464  { 465  free( result ); 466  return NULL; 467  } 468  result->num_elem_desc = ui; 469  470  /* allocate array of element descriptors */ 471  size = result->num_elem_desc * sizeof( struct mhdf_ElemDesc ); 472  ptr = realloc_data( &result, size, status, sizeof( char* ) ); 473  if( NULL == ptr ) 474  { 475  free( elem_handles ); 476  return NULL; 477  } 478  memset( ptr, 0, size ); 479  result->elems = ptr; 480  481  /* Initialize each element descriptor */ 482  for( i = 0; i < result->num_elem_desc; ++i ) 483  { 484  result = get_elem_desc( file_handle, result, elem_handles[i], i, status ); 485  if( NULL == result ) 486  { 487  free( elem_handles ); 488  return NULL; 489  } 490  } 491  492  /* get tag list */ 493  tag_names = mhdf_getTagNames( file_handle, &num_tag_names, status ); 494  if( mhdf_isError( status ) ) 495  { 496  free( elem_handles ); 497  free( result ); 498  return NULL; 499  } 500  501  /* allocate array of tag descriptors */ 502  size = num_tag_names * sizeof( struct mhdf_TagDesc ); 503  ptr = realloc_data( &result, size, status, sizeof( char* ) ); 504  if( NULL == ptr ) 505  { 506  free( elem_handles ); 507  free_string_list( tag_names, result->num_tag_desc ); 508  return NULL; 509  } 510  memset( ptr, 0, size ); 511  result->tags = ptr; 512  result->num_tag_desc = num_tag_names; 513  memset( result->tags, 0, size ); 514  515  /* Initialize each tag descriptor */ 516  for( i = 0; i < result->num_tag_desc; ++i ) 517  { 518  result = get_tag_desc( file_handle, result, tag_names[i], i, file_id_type, status ); 519  if( NULL == result ) 520  { 521  free( elem_handles ); 522  free_string_list( tag_names, num_tag_names ); 523  return NULL; 524  } 525  } 526  527  /* Determine which dense tags are present */ 528  529  size = ( 2 + result->num_elem_desc ) * result->num_tag_desc; 530  array = mhdf_malloc( size, status ); 531  if( NULL == array ) 532  { 533  free( elem_handles ); 534  free_string_list( tag_names, num_tag_names ); 535  free( result ); 536  return NULL; 537  } 538  memset( array, 0, size ); 539  matrix = array + ( 2 * result->num_tag_desc ); 540  541  for( j = 0; j < result->num_tag_desc; ++j ) 542  { 543  if( mhdf_haveDenseTag( file_handle, tag_names[j], mhdf_node_type_handle(), status ) ) 544  matrix[-1 * result->num_tag_desc + j] = 1; 545  if( mhdf_haveDenseTag( file_handle, tag_names[j], mhdf_set_type_handle(), status ) ) 546  matrix[-2 * result->num_tag_desc + j] = 1; 547  for( i = 0; i < result->num_elem_desc; ++i ) 548  if( mhdf_haveDenseTag( file_handle, tag_names[j], elem_handles[i], status ) ) 549  matrix[i * result->num_tag_desc + j] = 1; 550  } 551  free( elem_handles ); 552  free_string_list( tag_names, result->num_tag_desc ); 553  554  /* Populate dense tag lists for element types */ 555  for( i = -2; i < result->num_elem_desc; ++i ) 556  { 557  size = 0; 558  for( j = 0; j < result->num_tag_desc; ++j ) 559  size += matrix[i * result->num_tag_desc + j]; 560  if( !size ) 561  { 562  indices = NULL; 563  } 564  else 565  { 566  indices = realloc_data( &result, size * sizeof( int ), status, sizeof( int ) ); 567  if( NULL == indices ) 568  { 569  free( array ); 570  return NULL; 571  } 572  573  k = 0; 574  for( j = 0; j < result->num_tag_desc; ++j ) 575  if( matrix[i * result->num_tag_desc + j] ) indices[k++] = j; 576  assert( k == size ); 577  } 578  579  if( i == -2 ) 580  { 581  result->sets.dense_tag_indices = indices; 582  result->sets.num_dense_tags = size; 583  } 584  else if( i == -1 ) 585  { 586  result->nodes.dense_tag_indices = indices; 587  result->nodes.num_dense_tags = size; 588  } 589  else 590  { 591  result->elems[i].desc.dense_tag_indices = indices; 592  result->elems[i].desc.num_dense_tags = size; 593  } 594  } 595  596  /* Populate dense tag lists for each tag */ 597  for( j = 0; j < result->num_tag_desc; ++j ) 598  { 599  size = 0; 600  for( i = -2; i < result->num_elem_desc; ++i ) 601  size += matrix[i * result->num_tag_desc + j]; 602  if( !size ) 603  { 604  indices = 0; 605  } 606  else 607  { 608  indices = realloc_data( &result, size * sizeof( int ), status, sizeof( int ) ); 609  if( NULL == ptr ) 610  { 611  free( array ); 612  return NULL; 613  } 614  615  k = 0; 616  for( i = -2; i < result->num_elem_desc; ++i ) 617  if( matrix[i * result->num_tag_desc + j] ) indices[k++] = i; 618  assert( k == size ); 619  } 620  621  result->tags[j].num_dense_indices = size; 622  result->tags[j].dense_elem_indices = indices; 623  } 624  625  if( extraSetInfo ) 626  { 627  /* open the table for parallel partitions, material sets, neumann sets, 628  * dirichlet sets 629  * to determine number of parts, etc 630  * this is needed for iMOAB and VisIt plugin */ 631  const int NPRIMARY_SETS = 5; 632  ptr = realloc_data( &result, NPRIMARY_SETS * sizeof( int ), status, sizeof( int ) ); 633  if( NULL == ptr || mhdf_isError( status ) ) 634  { 635  free( array ); 636  return NULL; 637  } 638  result->numEntSets = ptr; 639  for( i = 0; i < NPRIMARY_SETS; ++i ) 640  result->numEntSets[i] = 0; 641  642  ptr = realloc_data( &result, NPRIMARY_SETS * sizeof( int* ), status, sizeof( int* ) ); 643  if( NULL == ptr || mhdf_isError( status ) ) 644  { 645  free( array ); 646  return NULL; 647  } 648  result->defTagsEntSets = ptr; 649  650  ptr = realloc_data( &result, NPRIMARY_SETS * sizeof( int* ), status, sizeof( int* ) ); 651  if( NULL == ptr || mhdf_isError( status ) ) 652  { 653  free( array ); 654  return NULL; 655  } 656  result->defTagsVals = ptr; 657  numtags = result->num_tag_desc; 658  659  for( i = 0; i < numtags; i++ ) 660  { 661  tag_desc = &( result->tags[i] ); 662  for( k = 0; k < NPRIMARY_SETS; k++ ) /* number of default tags to consider */ 663  { 664  if( strcmp( pname[k], tag_desc->name ) == 0 ) 665  { 666  if( tag_desc->have_sparse ) 667  { 668  mhdf_openSparseTagData( file_handle, pname[k], &nval, &junk, table, status ); 669  if( mhdf_isError( status ) ) 670  { 671  free( array ); 672  return NULL; 673  } 674  /* for sparse tags, read */ 675  result->numEntSets[k] = nval; 676  if( nval <= 0 ) continue; /* do not do anything */ 677  678  ptr = realloc_data( &result, nval * sizeof( int ), status, sizeof( int ) ); 679  if( NULL == ptr || mhdf_isError( status ) ) 680  { 681  free( array ); 682  return NULL; 683  } 684  memset( ptr, 0, nval * sizeof( int ) ); 685  result->defTagsEntSets[k] = ptr; 686  tag_desc = &( result->tags[i] ); 687  688  ptr = realloc_data( &result, nval * sizeof( int ), status, sizeof( int ) ); 689  if( NULL == ptr || mhdf_isError( status ) ) 690  { 691  free( array ); 692  return NULL; 693  } 694  memset( ptr, 0, nval * sizeof( int ) ); 695  result->defTagsVals[k] = ptr; 696  tag_desc = &( result->tags[i] ); /* this is because the tag might point to 697  something else*/ 698  699  /* make room for the long array type 700  is it long or something else? */ 701  id_list = mhdf_malloc( nval * sizeof( long ), status ); 702  /* fill the id with values, then convert to int type (-set start) 703  704  mhdf_read_data( table_id, offset, count, int_type, id_list, H5P_DEFAULT, 705  status );*/ 706  707  data_type = H5Dget_type( table[0] ); 708  709  mhdf_read_data( table[0], 0, nval, data_type, id_list, H5P_DEFAULT, status ); 710  if( mhdf_isError( status ) ) 711  { 712  free( array ); 713  return NULL; 714  } 715  H5Tclose( data_type ); 716  717  for( i1 = 0; i1 < nval; i1++ ) 718  result->defTagsEntSets[k][i1] = (int)( id_list[i1] - result->sets.start_id + 1 ); 719  /* now read values, integer type */ 720  data_type = H5Dget_type( table[1] ); 721  mhdf_read_data( table[1], 0, nval, data_type, result->defTagsVals[k], H5P_DEFAULT, status ); 722  if( mhdf_isError( status ) ) 723  { 724  free( array ); 725  return NULL; 726  } 727  H5Tclose( data_type ); 728  mhdf_closeData( file_handle, table[0], status ); 729  if( mhdf_isError( status ) ) 730  { 731  free( array ); 732  return NULL; 733  } 734  mhdf_closeData( file_handle, table[1], status ); 735  if( mhdf_isError( status ) ) 736  { 737  free( array ); 738  return NULL; 739  } 740  free( id_list ); 741  } 742  else if( 0 == k || 1 == k ) 743  { /* parallel partition or material sets should still work if dense 744  could be dense tags on sets */ 745  if( !mhdf_haveDenseTag( file_handle, pname[k], mhdf_set_type_handle(), status ) ) continue; 746  table[0] = 747  mhdf_openDenseTagData( file_handle, pname[k], mhdf_set_type_handle(), &nval, status ); 748  if( mhdf_isError( status ) ) 749  { 750  continue; /* do not error out if not a dense tag either */ 751  } 752  result->numEntSets[k] = nval; 753  if( nval <= 0 ) continue; /* do not do anything */ 754  755  /* 756  * if dense parallel partition or material set, we know what to expect 757  */ 758  result->numEntSets[k] = nval; /* k could be 0 or 1 */ 759  if( nval <= 0 ) continue; /* do not do anything */ 760  761  ptr = realloc_data( &result, nval * sizeof( int ), status, sizeof( int ) ); 762  if( NULL == ptr || mhdf_isError( status ) ) 763  { 764  free( array ); 765  return NULL; 766  } 767  memset( ptr, 0, nval * sizeof( int ) ); 768  result->defTagsEntSets[k] = ptr; 769  tag_desc = &( result->tags[i] ); 770  771  ptr = realloc_data( &result, nval * sizeof( int ), status, sizeof( int ) ); 772  if( NULL == ptr || mhdf_isError( status ) ) 773  { 774  free( array ); 775  return NULL; 776  } 777  memset( ptr, 0, nval * sizeof( int ) ); 778  result->defTagsVals[k] = ptr; 779  tag_desc = &( result->tags[i] ); /* this is because the tag might point to 780  something else*/ 781  782  for( i1 = 0; i1 < nval; i1++ ) 783  { 784  result->defTagsEntSets[k][i1] = i1 + 1; 785  /*result -> defTagsVals[k][i1] = i1; we know how the partition looks 786  * like */ 787  } 788  /* fill in the data with the dense tag values 789  because dense, sets will be in order 790  791  we know it has to be integer */ 792  mhdf_readTagValues( table[0], 0, nval, H5T_NATIVE_INT, result->defTagsVals[k], status ); 793  if( mhdf_isError( status ) ) 794  { 795  free( array ); 796  return NULL; 797  } 798  mhdf_closeData( file_handle, table[0], status ); 799  if( mhdf_isError( status ) ) 800  { 801  free( array ); 802  return NULL; 803  } 804  } 805  } 806  } 807  } 808  } 809  /* Compact memory and return */ 810  free( array ); 811  result->total_size = result->offset - (unsigned char*)result; 812  813  API_END; 814  return result; 815 }