Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
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  int 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;
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 
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 }