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