Branch data Line data Source code
1 : : /**
2 : : * MOAB, a Mesh-Oriented datABase, is a software component for creating,
3 : : * storing and accessing finite element mesh data.
4 : : *
5 : : * Copyright 2004 Sandia Corporation. Under the terms of Contract
6 : : * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
7 : : * retains certain rights in this software.
8 : : *
9 : : * This library is free software; you can redistribute it and/or
10 : : * modify it under the terms of the GNU Lesser General Public
11 : : * License as published by the Free Software Foundation; either
12 : : * version 2.1 of the License, or (at your option) any later version.
13 : : *
14 : : */
15 : :
16 : : #include <stdlib.h>
17 : : #include <string.h>
18 : : #include <H5Tpublic.h>
19 : : #include <H5Gpublic.h>
20 : : #include <H5Dpublic.h>
21 : : #include <H5Spublic.h> /* for H5S_MAX_RANK */
22 : : #include <H5Apublic.h>
23 : : #include <H5Ppublic.h>
24 : : #include "status.h"
25 : : #include "file-handle.h"
26 : : #include "mhdf.h"
27 : : #include "util.h"
28 : : #include "names-and-paths.h"
29 : :
30 : 0 : hid_t mhdf_getNativeType( hid_t input_type, int size, mhdf_Status* status )
31 : : {
32 : : H5T_sign_t sgn;
33 : : H5T_class_t cls;
34 : : hid_t tmp_id, type_id;
35 : :
36 : 0 : mhdf_setOkay( status );
37 : :
38 : 0 : cls = H5Tget_class( input_type );
39 [ # # # # : 0 : switch( cls )
# # ]
40 : : {
41 : : case H5T_FLOAT:
42 [ # # # # ]: 0 : switch( size )
43 : : {
44 : : case 4:
45 : 0 : return H5T_NATIVE_FLOAT;
46 : : case 8:
47 : 0 : return H5T_NATIVE_DOUBLE;
48 : : case 16:
49 : 0 : return H5T_NATIVE_LDOUBLE;
50 : : default:
51 : 0 : mhdf_setFail( status, "Invalid size for floating point type: %d", size );
52 : 0 : return -1;
53 : : }
54 : :
55 : : case H5T_INTEGER:
56 : 0 : sgn = H5Tget_sign( input_type );
57 [ # # ]: 0 : if( H5T_SGN_ERROR == sgn )
58 : : {
59 : 0 : mhdf_setFail( status, "Internall errror calling H5Tget_sign." );
60 : 0 : return -1;
61 : : }
62 [ # # ]: 0 : if( sizeof( char ) == size )
63 [ # # ]: 0 : return sgn == H5T_SGN_NONE ? H5T_NATIVE_UCHAR : H5T_NATIVE_SCHAR;
64 [ # # ]: 0 : else if( sizeof( short ) == size )
65 [ # # ]: 0 : return sgn == H5T_SGN_NONE ? H5T_NATIVE_USHORT : H5T_NATIVE_SHORT;
66 [ # # ]: 0 : else if( sizeof( int ) == size )
67 [ # # ]: 0 : return sgn == H5T_SGN_NONE ? H5T_NATIVE_UINT : H5T_NATIVE_INT;
68 [ # # ]: 0 : else if( sizeof( long ) == size )
69 [ # # ]: 0 : return sgn == H5T_SGN_NONE ? H5T_NATIVE_ULONG : H5T_NATIVE_LONG;
70 [ # # ]: 0 : else if( (int)H5Tget_size( H5T_NATIVE_LLONG ) == size )
71 [ # # ]: 0 : return sgn == H5T_SGN_NONE ? H5T_NATIVE_ULLONG : H5T_NATIVE_LLONG;
72 : :
73 : 0 : mhdf_setFail( status, "Invalid size for integer type: %d", size );
74 : 0 : return -1;
75 : :
76 : : case H5T_ENUM:
77 : 0 : tmp_id = H5Tget_super( input_type );
78 [ # # ]: 0 : if( tmp_id < 0 )
79 : : {
80 : 0 : mhdf_setFail( status, "Internal error calling H5Tget_super." );
81 : 0 : return -1;
82 : : }
83 : 0 : type_id = mhdf_getNativeType( tmp_id, size, status );
84 : 0 : H5Tclose( tmp_id );
85 : 0 : return type_id;
86 : :
87 : : case H5T_TIME:
88 : : case H5T_OPAQUE:
89 : : case H5T_REFERENCE:
90 : 0 : mhdf_setFail( status, "Unsupported type class." );
91 : 0 : return -1;
92 : :
93 : : case H5T_COMPOUND:
94 : : case H5T_VLEN:
95 : : case H5T_ARRAY:
96 : : case H5T_STRING:
97 : 0 : mhdf_setFail( status, "Only atomic types are supported." );
98 : 0 : return -1;
99 : :
100 : : default:
101 : 0 : mhdf_setFail( status, "Internal error calling H5Tget_class. Bad handle?" );
102 : 0 : return -1;
103 : : }
104 : : }
105 : :
106 : 1440 : static hid_t get_tag( mhdf_FileHandle file_handle, const char* tag_name, hid_t* id_type, mhdf_Status* status )
107 : : {
108 : : hid_t group_id, tag_id;
109 : : char* path;
110 : : FileHandle* file_ptr;
111 : :
112 : 1440 : file_ptr = (FileHandle*)file_handle;
113 [ - + ]: 1440 : if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
114 : :
115 [ + + ]: 1440 : if( NULL != id_type ) *id_type = file_ptr->id_type;
116 : :
117 : 1440 : path = mhdf_name_to_path_copy( tag_name, status );
118 [ - + ]: 1440 : if( NULL == path ) return -1;
119 : :
120 : : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
121 : 1440 : group_id = H5Gopen2( file_ptr->hdf_handle, TAG_GROUP, H5P_DEFAULT );
122 : : #else
123 : : group_id = H5Gopen( file_ptr->hdf_handle, TAG_GROUP );
124 : : #endif
125 [ - + ]: 1440 : if( group_id < 0 )
126 : : {
127 : 0 : mhdf_setFail( status, "Failed to open tag group." );
128 : 0 : free( path );
129 : 0 : return -1;
130 : : }
131 : :
132 : : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
133 : 1440 : tag_id = H5Gopen2( group_id, path, H5P_DEFAULT );
134 : : #else
135 : : tag_id = H5Gopen( group_id, path );
136 : : #endif
137 : 1440 : H5Gclose( group_id );
138 : 1440 : free( path );
139 [ - + ]: 1440 : if( tag_id < 0 )
140 : : {
141 : 0 : mhdf_setFail( status, "Failed to open tag data for tag \"%s\".", tag_name );
142 : 0 : return -1;
143 : : }
144 : :
145 : 1440 : mhdf_setOkay( status );
146 : 1440 : return tag_id;
147 : : }
148 : :
149 : 106 : static hid_t get_tag_type( FileHandle* file_ptr, const char* tag_path, mhdf_Status* status )
150 : : {
151 : : hid_t group_id, tag_id, type_id;
152 : :
153 : : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
154 : 106 : group_id = H5Gopen2( file_ptr->hdf_handle, TAG_GROUP, H5P_DEFAULT );
155 : : #else
156 : : group_id = H5Gopen( file_ptr->hdf_handle, TAG_GROUP );
157 : : #endif
158 [ - + ]: 106 : if( group_id < 0 )
159 : : {
160 : 0 : mhdf_setFail( status, "Failed to open tag group." );
161 : 0 : return -1;
162 : : }
163 : :
164 : : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
165 : 106 : tag_id = H5Gopen2( group_id, tag_path, H5P_DEFAULT );
166 : : #else
167 : : tag_id = H5Gopen( group_id, tag_path );
168 : : #endif
169 : 106 : H5Gclose( group_id );
170 [ - + ]: 106 : if( tag_id < 0 )
171 : : {
172 : 0 : mhdf_setFail( status, "Failed to open group for tag \"%s\".", tag_path );
173 : 0 : return -1;
174 : : }
175 : :
176 : : #if defined( H5Topen_vers ) && H5Topen_vers > 1
177 : 106 : type_id = H5Topen2( tag_id, TAG_TYPE_NAME, H5P_DEFAULT );
178 : : #else
179 : : type_id = H5Topen( tag_id, TAG_TYPE_NAME );
180 : : #endif
181 : 106 : H5Gclose( tag_id );
182 [ - + ]: 106 : if( type_id < 0 )
183 : : {
184 : 0 : mhdf_setFail( status, "Failed to open type data for tag \"%s\".", tag_path );
185 : 0 : return -1;
186 : : }
187 : :
188 : 106 : return type_id;
189 : : }
190 : :
191 : : /** Helper function to write default and mesh values for tag
192 : : *\param tag_id The file object upon which to attach the attribute
193 : : *\param attrib_name The name of the attribute object
194 : : *\param type_id The data type of the attribute data
195 : : *\param value Pointer to attribute data
196 : : *\param value_size Size of attribute data, as multiple of type indicated
197 : : * by type_id. Should be 1 except for variable-length tag data.
198 : : */
199 : 448 : static int store_tag_val_in_attrib( hid_t tag_id, const char* attrib_name, hid_t type_id, const void* value,
200 : : hsize_t value_size, mhdf_Status* status )
201 : : {
202 : : hid_t write_type;
203 : : int rval;
204 [ + - ]: 448 : if( value_size == 1 )
205 : 448 : write_type = type_id;
206 [ # # ]: 0 : else if( H5Tget_class( type_id ) == H5T_OPAQUE )
207 : : {
208 : 0 : write_type = H5Tcreate( H5T_OPAQUE, value_size );
209 : : }
210 : : else
211 : : {
212 : : #if defined( H5Tarray_create_vers ) && H5Tarray_create_vers > 1
213 : 0 : write_type = H5Tarray_create2( type_id, 1, &value_size );
214 : : #else
215 : : write_type = H5Tarray_create( type_id, 1, &value_size, 0 );
216 : : #endif
217 : : }
218 : :
219 [ - + ]: 448 : if( write_type < 0 )
220 : : {
221 : 0 : mhdf_setFail( status, "Error constructing type object for tag mesh/default value" );
222 : 0 : return -1;
223 : : }
224 : :
225 : 448 : rval = mhdf_create_scalar_attrib( tag_id, attrib_name, write_type, value, status );
226 [ - + ]: 448 : if( write_type != type_id ) H5Tclose( write_type );
227 : :
228 : 448 : return rval;
229 : : }
230 : :
231 : 347 : static hid_t create_tag_common( mhdf_FileHandle file_handle, const char* tag_name, enum mhdf_TagDataType tag_type,
232 : : int size, int storage, const void* default_value, int default_value_size_in,
233 : : const void* global_value, int global_value_size_in, hid_t hdf_type, hid_t hdf_base_type,
234 : : mhdf_Status* status )
235 : : {
236 : : hid_t temp_id, group_id, tag_id;
237 : : char* path;
238 : : FileHandle* file_ptr;
239 : : herr_t rval;
240 : : hsize_t arr_len;
241 : 347 : int one = 1, var_len = 0;
242 : 347 : hsize_t default_value_size = default_value_size_in;
243 : 347 : hsize_t global_value_size = global_value_size_in;
244 : 347 : int close_base_type = 0;
245 : :
246 : : /* Force standard data types over user-specified types */
247 : :
248 [ + + ]: 347 : if( tag_type != mhdf_OPAQUE ) hdf_type = 0;
249 [ + + ]: 347 : if( tag_type != mhdf_ENTITY_ID ) hdf_base_type = 0;
250 : :
251 : : /* Validate input */
252 : :
253 : 347 : file_ptr = (FileHandle*)file_handle;
254 [ - + ]: 347 : if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
255 : :
256 [ + - ][ - + ]: 347 : if( !tag_name || !*tag_name )
257 : : {
258 : 0 : mhdf_setFail( status, "Invalid tag name" );
259 : 0 : return -1;
260 : : }
261 : :
262 : : /* Open the tag group */
263 : :
264 : : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
265 : 347 : group_id = H5Gopen2( file_ptr->hdf_handle, TAG_GROUP, H5P_DEFAULT );
266 : : #else
267 : : group_id = H5Gopen( file_ptr->hdf_handle, TAG_GROUP );
268 : : #endif
269 [ - + ]: 347 : if( group_id < 0 )
270 : : {
271 : 0 : mhdf_setFail( status, "H5Gopen(\"%s\") failed.", TAG_GROUP );
272 : 0 : return -1;
273 : : }
274 : :
275 : : /* Create path string for tag object */
276 : :
277 : 347 : path = mhdf_name_to_path_copy( tag_name, status );
278 [ - + ]: 347 : if( !path )
279 : : {
280 : 0 : H5Gclose( group_id );
281 : 0 : return -1;
282 : : }
283 : :
284 : : /* Create group for this tag */
285 : :
286 : : #if defined( H5Gcreate_vers ) && H5Gcreate_vers > 1
287 : 347 : tag_id = H5Gcreate2( group_id, path, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
288 : : #else
289 : : tag_id = H5Gcreate( group_id, path, 3 );
290 : : #endif
291 [ - + ]: 347 : if( tag_id < 0 )
292 : : {
293 : 0 : mhdf_setFail( status, "H5Gcreate( \"%s\" ) failed.", path );
294 : 0 : free( path );
295 : 0 : H5Gclose( group_id );
296 : 0 : return -1;
297 : : }
298 : :
299 : : /* Store the tag name as the comment on the group entry */
300 : :
301 : 347 : rval = H5Gset_comment( group_id, path, tag_name );
302 : 347 : H5Gclose( group_id );
303 : 347 : free( path );
304 [ - + ]: 347 : if( rval < 0 )
305 : : {
306 : 0 : mhdf_setFail( status, "H5Gset_comment failed for tag \"%s\"", tag_name );
307 : 0 : H5Gclose( tag_id );
308 : 0 : return -1;
309 : : }
310 : :
311 : : /* Store TSTT tag type as attribute */
312 : :
313 : 347 : rval = mhdf_create_scalar_attrib( tag_id, TAG_TYPE_ATTRIB, H5T_NATIVE_INT, &storage, status );
314 [ - + ]: 347 : if( !rval )
315 : : {
316 : 0 : H5Gclose( tag_id );
317 : 0 : return -1;
318 : : }
319 : :
320 [ + + ]: 347 : if( hdf_type )
321 : : {
322 : 17 : hdf_type = H5Tcopy( hdf_type );
323 : 17 : arr_len = 1;
324 : : }
325 : : else
326 : : {
327 [ - - + - : 330 : switch( tag_type )
+ + ]
328 : : {
329 : : default:
330 : : case mhdf_OPAQUE:
331 : 0 : arr_len = 1;
332 : 0 : hdf_type = H5Tcreate( H5T_OPAQUE, abs( size ) );
333 : 0 : H5Tset_tag( hdf_type, "tag_data" );
334 : 0 : break;
335 : :
336 : : case mhdf_BITFIELD:
337 : 0 : arr_len = 1;
338 [ # # ]: 0 : if( size <= 0 )
339 : : {
340 : 0 : mhdf_setFail( status, "Invalid size (%d) for bit tag.", (int)size );
341 : 0 : return -1;
342 : : }
343 [ # # ]: 0 : else if( size <= 8 )
344 : 0 : hdf_type = H5Tcopy( H5T_NATIVE_B8 );
345 [ # # ]: 0 : else if( size <= 16 )
346 : 0 : hdf_type = H5Tcopy( H5T_NATIVE_B16 );
347 [ # # ]: 0 : else if( size <= 32 )
348 : 0 : hdf_type = H5Tcopy( H5T_NATIVE_B32 );
349 [ # # ]: 0 : else if( size <= 64 )
350 : 0 : hdf_type = H5Tcopy( H5T_NATIVE_B64 );
351 : : else
352 : : {
353 : 0 : mhdf_setFail( status, "Cannot create a bit tag larger than 64-bits. %d bits requested.\n",
354 : : (int)size );
355 : 0 : return -1;
356 : : }
357 : :
358 [ # # ]: 0 : if( 0 > H5Tset_precision( hdf_type, size ) )
359 : : {
360 : 0 : mhdf_setFail( status, "H5Tset_precision failed." );
361 : 0 : return -1;
362 : : }
363 : 0 : break;
364 : :
365 : : case mhdf_ENTITY_ID:
366 : 47 : arr_len = abs( size );
367 : 47 : hdf_type = H5Tcopy( H5T_NATIVE_ULONG );
368 : 47 : break;
369 : :
370 : : case mhdf_BOOLEAN:
371 : 0 : arr_len = abs( size );
372 : 0 : hdf_type = H5Tcopy( H5T_NATIVE_UCHAR );
373 : 0 : break;
374 : :
375 : : case mhdf_INTEGER:
376 : 252 : arr_len = abs( size );
377 : 252 : hdf_type = H5Tcopy( H5T_NATIVE_INT );
378 : 252 : break;
379 : :
380 : : case mhdf_FLOAT:
381 : 31 : arr_len = abs( size );
382 : 31 : hdf_type = H5Tcopy( H5T_NATIVE_DOUBLE );
383 : 31 : break;
384 : : }
385 : : }
386 : :
387 [ - + ]: 347 : if( hdf_type <= 0 )
388 : : {
389 : 0 : mhdf_setFail( status, "Failed to create tag type object." );
390 : 0 : H5Gclose( tag_id );
391 : 0 : return -1;
392 : : }
393 : :
394 [ + + ][ - + ]: 347 : if( hdf_base_type && H5Tget_class( hdf_type ) != H5Tget_class( hdf_base_type ) )
395 : : {
396 : 0 : mhdf_setFail( status, "Invalid base type for tag default/global data" );
397 : 0 : H5Gclose( tag_id );
398 : 0 : return -1;
399 : : }
400 : :
401 [ + - ][ - + ]: 347 : if( size < -1 || !arr_len )
402 : : {
403 : 0 : mhdf_setFail( status, "Invalid 'size' parameter passed to mhdf_createTag (%d)", (int)size );
404 : 0 : H5Gclose( tag_id );
405 : 0 : return -1;
406 : : }
407 [ + + ]: 347 : else if( size == -1 )
408 : : {
409 : : /* Note: we don't do anything with this here. We rely on
410 : : * the app to ask us to create the index table later.
411 : : */
412 : 24 : arr_len = 1;
413 : : /* need to know this later, when storing default/global values */
414 : 24 : var_len = 1;
415 : : }
416 [ + + ]: 323 : else if( arr_len > 1 )
417 : : {
418 : : #if defined( H5Tarray_create_vers ) && H5Tarray_create_vers > 1
419 : 33 : temp_id = H5Tarray_create2( hdf_type, 1, &arr_len );
420 : : #else
421 : : temp_id = H5Tarray_create( hdf_type, 1, &arr_len, NULL );
422 : : #endif
423 : 33 : H5Tclose( hdf_type );
424 [ - + ]: 33 : if( temp_id < 0 )
425 : : {
426 : 0 : mhdf_setFail( status, "Failed to create tag type object." );
427 : 0 : H5Gclose( tag_id );
428 : 0 : return -1;
429 : : }
430 : 33 : hdf_type = temp_id;
431 : :
432 [ + + ]: 33 : if( hdf_base_type )
433 : : {
434 [ - + ]: 12 : if( H5Tequal( hdf_base_type, hdf_type ) > 0 ) { hdf_base_type = hdf_type; }
435 : : else
436 : : {
437 : : #if defined( H5Tarray_create_vers ) && H5Tarray_create_vers > 1
438 : 12 : temp_id = H5Tarray_create2( hdf_base_type, 1, &arr_len );
439 : : #else
440 : : temp_id = H5Tarray_create( hdf_base_type, 1, &arr_len, NULL );
441 : : #endif
442 [ - + ]: 12 : if( temp_id < 0 )
443 : : {
444 : 0 : mhdf_setFail( status, "Failed to create tag type object." );
445 : 0 : H5Gclose( tag_id );
446 : 0 : H5Tclose( hdf_type );
447 : 0 : return -1;
448 : : }
449 : 12 : hdf_base_type = temp_id;
450 : 12 : close_base_type = 1;
451 : : }
452 : : }
453 : : }
454 : :
455 [ + + ]: 347 : if( !hdf_base_type ) hdf_base_type = hdf_type;
456 : :
457 : : /* Create tag type object, or write attribute if opaque */
458 : :
459 : : #if defined( H5Tcommit_vers ) && H5Tcommit_vers > 1
460 : 347 : rval = H5Tcommit2( tag_id, TAG_TYPE_NAME, hdf_type, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
461 : : #else
462 : : rval = H5Tcommit( tag_id, TAG_TYPE_NAME, hdf_type );
463 : : #endif
464 [ - + ]: 347 : if( rval < 0 )
465 : : {
466 : 0 : mhdf_setFail( status, "H5Tcommit failed for tag \"%s\"", tag_name );
467 [ # # ]: 0 : if( close_base_type ) H5Tclose( hdf_base_type );
468 : 0 : H5Tclose( hdf_type );
469 : 0 : H5Gclose( tag_id );
470 : 0 : return -1;
471 : : }
472 : :
473 : : /* If tag is entity handle, make note of it */
474 [ + + ]: 347 : if( tag_type == mhdf_ENTITY_ID )
475 : : {
476 : 47 : rval = mhdf_create_scalar_attrib( tag_id, TAG_HANDLE_TYPE_ATTRIB, H5T_NATIVE_INT, &one, status );
477 [ - + ]: 47 : if( !rval )
478 : : {
479 [ # # ]: 0 : if( close_base_type ) H5Tclose( hdf_base_type );
480 : 0 : H5Gclose( tag_id );
481 : 0 : H5Tclose( hdf_type );
482 : 0 : return -1;
483 : : }
484 : : }
485 : :
486 : : /* Store the default value as a attribute of the tag group */
487 : :
488 [ + + ]: 347 : if( default_value )
489 : : {
490 [ - + ]: 228 : rval = store_tag_val_in_attrib( tag_id, TAG_DEFAULT_ATTRIB, hdf_base_type, default_value,
491 : : var_len ? default_value_size : 1, status );
492 [ - + ]: 228 : if( !rval )
493 : : {
494 [ # # ]: 0 : if( close_base_type ) H5Tclose( hdf_base_type );
495 : 0 : H5Gclose( tag_id );
496 : 0 : H5Tclose( hdf_type );
497 : 0 : return -1;
498 : : }
499 : : }
500 : :
501 : : /* Store global tag value as attribute */
502 : :
503 [ + + ]: 347 : if( global_value )
504 : : {
505 [ - + ]: 220 : rval = store_tag_val_in_attrib( tag_id, TAG_GLOBAL_ATTRIB, hdf_base_type, global_value,
506 : : var_len ? global_value_size : 1, status );
507 [ - + ]: 220 : if( !rval )
508 : : {
509 [ # # ]: 0 : if( close_base_type ) H5Tclose( hdf_base_type );
510 : 0 : H5Gclose( tag_id );
511 : 0 : H5Tclose( hdf_type );
512 : 0 : return -1;
513 : : }
514 : : }
515 : :
516 [ + + ]: 347 : if( close_base_type ) H5Tclose( hdf_base_type );
517 : 347 : H5Tclose( hdf_type );
518 : 347 : mhdf_setOkay( status );
519 : 347 : return tag_id;
520 : : }
521 : :
522 : 0 : hid_t mhdf_getTagDataType( mhdf_FileHandle file_handle, const char* tag_name, mhdf_Status* status )
523 : : {
524 : : FileHandle* file_ptr;
525 : : hid_t result;
526 : : char* path;
527 : : API_BEGIN;
528 : :
529 : : /* Validate input */
530 : :
531 : 0 : file_ptr = (FileHandle*)file_handle;
532 [ # # ]: 0 : if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
533 : :
534 [ # # ][ # # ]: 0 : if( !tag_name || !*tag_name )
535 : : {
536 : 0 : mhdf_setFail( status, "Invalid tag name" );
537 : 0 : return -1;
538 : : }
539 : :
540 : : /* Create path string for tag object */
541 : :
542 : 0 : path = mhdf_name_to_path_copy( tag_name, status );
543 [ # # ]: 0 : if( !path ) { return -1; }
544 : :
545 : 0 : result = get_tag_type( file_ptr, path, status );
546 : :
547 : 0 : free( path );
548 : : API_END;
549 : 0 : return result;
550 : : }
551 : :
552 : 323 : void mhdf_createTag( mhdf_FileHandle file_handle, const char* tag_name, enum mhdf_TagDataType tag_type, int size,
553 : : int storage, const void* default_value, const void* global_value, hid_t hdf_type,
554 : : hid_t hdf_base_type, mhdf_Status* status )
555 : : {
556 : : hid_t tag_id;
557 : : API_BEGIN;
558 : 323 : tag_id = create_tag_common( file_handle, tag_name, tag_type, size, storage, default_value, 1, global_value, 1,
559 : : hdf_type, hdf_base_type, status );
560 [ + - ]: 323 : if( tag_id >= 0 ) H5Gclose( tag_id );
561 : : API_END;
562 : 323 : }
563 : :
564 : 24 : void mhdf_createVarLenTag( mhdf_FileHandle file_handle, const char* tag_name, enum mhdf_TagDataType tag_type,
565 : : int storage, const void* default_value, int default_value_length, const void* global_value,
566 : : int global_value_length, hid_t hdf_type, hid_t hdf_base_type, mhdf_Status* status )
567 : : {
568 : : hid_t tag_id;
569 : 24 : int one = 1;
570 : :
571 : : API_BEGIN;
572 : 24 : tag_id = create_tag_common( file_handle, tag_name, tag_type, -1, storage, default_value, default_value_length,
573 : : global_value, global_value_length, hdf_type, hdf_base_type, status );
574 [ + - ]: 24 : if( tag_id >= 0 )
575 : : {
576 : 24 : mhdf_create_scalar_attrib( tag_id, TAG_VARLEN_ATTRIB, H5T_NATIVE_INT, &one, status );
577 : 24 : H5Gclose( tag_id );
578 : : }
579 : : API_END;
580 : 24 : }
581 : :
582 : 0 : int mhdf_getNumberTags( mhdf_FileHandle file_handle, mhdf_Status* status )
583 : : {
584 : : hid_t group_id;
585 : : hsize_t result;
586 : : FileHandle* file_ptr;
587 : : API_BEGIN;
588 : :
589 : : /* Validate input */
590 : :
591 : 0 : file_ptr = (FileHandle*)file_handle;
592 [ # # ]: 0 : if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
593 : :
594 : : /* Open the tags group */
595 : :
596 : : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
597 : 0 : group_id = H5Gopen2( file_ptr->hdf_handle, TAG_GROUP, H5P_DEFAULT );
598 : : #else
599 : : group_id = H5Gopen( file_ptr->hdf_handle, TAG_GROUP );
600 : : #endif
601 [ # # ]: 0 : if( group_id < 0 )
602 : : {
603 : 0 : mhdf_setFail( status, "H5Gopen(\"%s\") failed", TAG_GROUP );
604 : 0 : return -1;
605 : : }
606 : :
607 : : /* Get number of objects in tags group */
608 : :
609 [ # # ]: 0 : if( H5Gget_num_objs( group_id, &result ) < 0 )
610 : : {
611 : 0 : mhdf_setFail( status, "Internal failure calling H5Gget_num_objs." );
612 : 0 : H5Gclose( group_id );
613 : 0 : return -1;
614 : : }
615 : :
616 : 0 : H5Gclose( group_id );
617 : 0 : mhdf_setOkay( status );
618 : : API_END;
619 : 0 : return (int)result;
620 : : }
621 : :
622 : 68 : char** mhdf_getTagNames( mhdf_FileHandle file_handle, int* num_names_out, mhdf_Status* status )
623 : : {
624 : : hid_t group_id;
625 : : FileHandle* file_ptr;
626 : : hsize_t count, idx;
627 : : char* name;
628 : : char** result;
629 : : ssize_t size;
630 : : API_BEGIN;
631 : :
632 : : /* Validate input */
633 : :
634 : 68 : file_ptr = (FileHandle*)file_handle;
635 [ - + ]: 68 : if( !mhdf_check_valid_file( file_ptr, status ) ) return NULL;
636 : :
637 : : /* Open the tags group */
638 : :
639 : : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
640 : 68 : group_id = H5Gopen2( file_ptr->hdf_handle, TAG_GROUP, H5P_DEFAULT );
641 : : #else
642 : : group_id = H5Gopen( file_ptr->hdf_handle, TAG_GROUP );
643 : : #endif
644 [ - + ]: 68 : if( group_id < 0 )
645 : : {
646 : 0 : mhdf_setFail( status, "H5Gopen(\"%s\") failed", TAG_GROUP );
647 : 0 : return NULL;
648 : : }
649 : :
650 : : /* Get number of objects in tags group */
651 : :
652 [ - + ]: 68 : if( H5Gget_num_objs( group_id, &count ) < 0 )
653 : : {
654 : 0 : mhdf_setFail( status, "Internal failure calling H5Gget_num_objs." );
655 : 0 : H5Gclose( group_id );
656 : 0 : return NULL;
657 : : }
658 : :
659 : : /* No tags? */
660 : :
661 : 68 : *num_names_out = (int)count;
662 [ - + ]: 68 : if( count == 0 )
663 : : {
664 : 0 : H5Gclose( group_id );
665 : 0 : mhdf_setOkay( status );
666 : 0 : return NULL;
667 : : }
668 : :
669 : : /* Allocate string array */
670 : :
671 : 68 : result = (char**)mhdf_malloc( sizeof( char* ) * count, status );
672 [ - + ]: 68 : if( NULL == result )
673 : : {
674 : 0 : H5Gclose( group_id );
675 : 0 : return NULL;
676 : : }
677 : :
678 : : /* Get names */
679 : :
680 [ + + ]: 706 : for( idx = 0; idx < count; ++idx )
681 : : {
682 : 638 : size = H5Gget_objname_by_idx( group_id, idx, NULL, 0 );
683 [ + - ][ - + ]: 638 : if( size < 1 || NULL == ( name = (char*)mhdf_malloc( size + 1, status ) ) )
684 : : {
685 [ # # ]: 0 : while( ( --idx ) > 0 )
686 : 0 : free( result[ idx ] );
687 : 0 : free( result );
688 : 0 : H5Gclose( group_id );
689 : 0 : mhdf_setFail( status, "Internal failure calling H5Gget_objname_by_idx." );
690 : 0 : return NULL;
691 : : }
692 : :
693 : 638 : H5Gget_objname_by_idx( group_id, idx, name, size + 1 );
694 [ - + ]: 638 : if( !mhdf_path_to_name( name, name ) )
695 : : {
696 : 0 : mhdf_setFail( status, "Invalid character string in internal file path: \"%s\"\n", name );
697 : 0 : return NULL;
698 : : }
699 : 638 : result[ idx ] = name;
700 : : }
701 : :
702 : 68 : H5Gclose( group_id );
703 : 68 : mhdf_setOkay( status );
704 : : API_END;
705 : 68 : return result;
706 : : }
707 : :
708 : 0 : static int get_attrib_array_length_handle( hid_t attrib_id )
709 : : {
710 : : hid_t type_id;
711 : : int rank;
712 : : hsize_t dims[ H5S_MAX_RANK ];
713 : : int perm[ H5S_MAX_RANK ];
714 : :
715 : 0 : type_id = H5Aget_type( attrib_id );
716 [ # # # # ]: 0 : switch( H5Tget_class( type_id ) )
717 : : {
718 : : case H5T_NO_CLASS:
719 : 0 : dims[ 0 ] = -1;
720 : 0 : break;
721 : : case H5T_OPAQUE:
722 : 0 : dims[ 0 ] = H5Tget_size( type_id );
723 : 0 : break;
724 : : case H5T_ARRAY:
725 : : #if defined( H5Tget_array_dims_vers ) && H5Tget_array_dims_vers > 1
726 : : (void)perm; /* suppress warning */
727 : 0 : rank = H5Tget_array_dims2( type_id, dims );
728 : : #else
729 : : rank = H5Tget_array_dims( type_id, dims, perm );
730 : : #endif
731 [ # # ]: 0 : if( rank == 1 )
732 : 0 : break;
733 : : else
734 : 0 : return -1;
735 : : default:
736 : 0 : dims[ 0 ] = 1;
737 : 0 : break;
738 : : }
739 : :
740 : 0 : H5Tclose( type_id );
741 : 0 : return dims[ 0 ];
742 : : }
743 : :
744 : : /*
745 : : static int get_attrib_array_length_index( hid_t object_id, unsigned int index )
746 : : {
747 : : hid_t attrib_id;
748 : : int result;
749 : :
750 : : attrib_id = H5Aopen_idx( object_id, index );
751 : : if (attrib_id < 0)
752 : : return -1;
753 : :
754 : : result = get_attrib_array_length_handle( attrib_id );
755 : : H5Aclose( attrib_id );
756 : : return result;
757 : : }
758 : : */
759 : :
760 : 0 : static int get_attrib_array_length_name( hid_t file, const char* path )
761 : : {
762 : : hid_t attrib_id;
763 : : int result;
764 : :
765 : 0 : attrib_id = H5Aopen_name( file, path );
766 [ # # ]: 0 : if( attrib_id < 0 ) return -1;
767 : :
768 : 0 : result = get_attrib_array_length_handle( attrib_id );
769 : 0 : H5Aclose( attrib_id );
770 : 0 : return result;
771 : : }
772 : :
773 : 638 : void mhdf_getTagInfo( mhdf_FileHandle file_handle, const char* tag_name, enum mhdf_TagDataType* class_out,
774 : : int* size_out, int* tstt_storage_out, int* have_default_out, int* have_global_out,
775 : : int* have_sparse_out, mhdf_Status* status )
776 : : {
777 : : hid_t tag_id, type_id, super_id;
778 : : int i, rval, is_handle;
779 : : hsize_t size, sup_size;
780 : : unsigned int idx;
781 : : int rank, var_data;
782 : : hsize_t dims[ H5S_MAX_RANK ];
783 : : int perm[ H5S_MAX_RANK ];
784 : : H5T_class_t class_tmp;
785 : :
786 : : API_BEGIN;
787 : :
788 : : /* Validate input */
789 [ + - ][ + - ]: 638 : if( NULL == tag_name || NULL == class_out || NULL == size_out || NULL == tstt_storage_out ||
[ + - ][ + - ]
[ + - ]
790 [ + - ][ - + ]: 638 : NULL == have_default_out || NULL == have_global_out || NULL == have_sparse_out )
791 : : {
792 : 0 : mhdf_setFail( status, "Invalid input." );
793 : 0 : return;
794 : : }
795 : :
796 : : /* Get group for tag */
797 : 638 : tag_id = get_tag( file_handle, tag_name, NULL, status );
798 [ - + ]: 638 : if( tag_id < 0 ) return;
799 : :
800 : : /* Check for sparse data */
801 : 638 : rval = mhdf_is_in_group( tag_id, SPARSE_ENTITY_NAME, status );
802 [ - + ]: 638 : if( rval < 0 )
803 : : {
804 : 0 : H5Gclose( tag_id );
805 : 0 : return;
806 : : }
807 : 638 : *have_sparse_out = rval ? 1 : 0;
808 : :
809 : : /* Check for variable-length tag data */
810 : 638 : rval = mhdf_find_attribute( tag_id, TAG_VARLEN_ATTRIB, &idx, status );
811 [ - + ]: 638 : if( rval < 0 )
812 : : {
813 : 0 : H5Gclose( tag_id );
814 : 0 : return;
815 : : }
816 : 638 : var_data = rval ? 1 : 0;
817 : :
818 : : /* Check if have default value for tag */
819 : 638 : rval = mhdf_find_attribute( tag_id, TAG_DEFAULT_ATTRIB, &idx, status );
820 [ - + ]: 638 : if( rval < 0 )
821 : : {
822 : 0 : H5Gclose( tag_id );
823 : 0 : return;
824 : : }
825 [ + + ]: 638 : if( !rval )
826 : 315 : *have_default_out = 0;
827 [ + - ]: 323 : else if( !var_data )
828 : 323 : *have_default_out = 1;
829 : : else
830 : : {
831 : : /* *have_default_out = get_attrib_array_length_index( tag_id, index ); */
832 : 0 : *have_default_out = get_attrib_array_length_name( tag_id, TAG_DEFAULT_ATTRIB );
833 [ # # ]: 0 : if( *have_default_out < 0 )
834 : : {
835 : 0 : mhdf_setFail( status, "Error checking length of default value for tag: %s\n", tag_name );
836 : 0 : H5Gclose( tag_id );
837 : 0 : return;
838 : : }
839 : : }
840 : :
841 : : /* Check if have global value for tag */
842 : 638 : rval = mhdf_find_attribute( tag_id, TAG_GLOBAL_ATTRIB, &idx, status );
843 [ - + ]: 638 : if( rval < 0 )
844 : : {
845 : 0 : H5Gclose( tag_id );
846 : 0 : return;
847 : : }
848 [ + + ]: 638 : if( !rval )
849 : 336 : *have_global_out = 0;
850 [ + - ]: 302 : else if( !var_data )
851 : 302 : *have_global_out = 1;
852 : : else
853 : : {
854 : : /* *have_global_out = get_attrib_array_length_index( tag_id, index ); */
855 : 0 : *have_global_out = get_attrib_array_length_name( tag_id, TAG_GLOBAL_ATTRIB );
856 [ # # ]: 0 : if( *have_global_out < 0 )
857 : : {
858 : 0 : mhdf_setFail( status, "Error checking length of global value for tag: %s\n", tag_name );
859 : 0 : H5Gclose( tag_id );
860 : 0 : return;
861 : : }
862 : : }
863 : :
864 : : /* Get TSTT tag class */
865 : 638 : rval = mhdf_read_scalar_attrib( tag_id, TAG_TYPE_ATTRIB, H5T_NATIVE_INT, tstt_storage_out, status );
866 [ - + ]: 638 : if( rval < 1 )
867 : : {
868 : 0 : H5Gclose( tag_id );
869 : 0 : return;
870 : : }
871 : :
872 : : /* Check if tag is storing entity handles */
873 : 638 : rval = mhdf_find_attribute( tag_id, TAG_HANDLE_TYPE_ATTRIB, &idx, status );
874 [ - + ]: 638 : if( rval < 0 )
875 : : {
876 : 0 : H5Gclose( tag_id );
877 : 0 : return;
878 : : }
879 : 638 : is_handle = rval;
880 : :
881 : : /* Get tag type */
882 : : #if defined( H5Topen_vers ) && H5Topen_vers > 1
883 : 638 : type_id = H5Topen2( tag_id, TAG_TYPE_NAME, H5P_DEFAULT );
884 : : #else
885 : : type_id = H5Topen( tag_id, TAG_TYPE_NAME );
886 : : #endif
887 [ - + ]: 638 : if( type_id < 0 )
888 : : {
889 : 0 : H5Gclose( tag_id );
890 : 0 : mhdf_setFail( status, "Failed to get type object for tag \"%s\".", tag_name );
891 : 0 : return;
892 : : }
893 : :
894 : 638 : class_tmp = H5Tget_class( type_id );
895 [ - + ]: 638 : if( class_tmp < 0 )
896 : : {
897 : 0 : mhdf_setFail( status, "H5Tget_class failed." );
898 : 0 : H5Gclose( tag_id );
899 : 0 : H5Tclose( type_id );
900 : 0 : return;
901 : : }
902 : :
903 : 638 : size = H5Tget_size( type_id );
904 [ - + ]: 638 : if( size <= 0 )
905 : : {
906 : 0 : mhdf_setFail( status, "H5Tget_size failed." );
907 : 0 : H5Gclose( tag_id );
908 : 0 : H5Tclose( type_id );
909 : 0 : return;
910 : : }
911 : :
912 [ + + - + : 638 : switch( class_tmp )
+ ]
913 : : {
914 : : case H5T_INTEGER:
915 [ - + ]: 477 : *class_out = ( size == 1 ) ? mhdf_BOOLEAN : mhdf_INTEGER;
916 : 477 : *size_out = 1;
917 : 477 : break;
918 : :
919 : : case H5T_FLOAT:
920 : 43 : *class_out = mhdf_FLOAT;
921 : 43 : *size_out = 1;
922 : 43 : break;
923 : :
924 : : case H5T_BITFIELD:
925 : 0 : *class_out = mhdf_BITFIELD;
926 : 0 : *size_out = H5Tget_precision( type_id );
927 [ # # ]: 0 : if( *size_out <= 0 )
928 : : {
929 : 0 : mhdf_setFail( status, "H5Tget_precision failed." );
930 : 0 : H5Gclose( tag_id );
931 : 0 : H5Tclose( type_id );
932 : 0 : return;
933 : : }
934 : 0 : break;
935 : :
936 : : default:
937 : : case H5T_OPAQUE:
938 : 46 : *class_out = mhdf_OPAQUE;
939 : 46 : *size_out = size;
940 : 46 : break;
941 : :
942 : : case H5T_ARRAY:
943 : :
944 : : #if defined( H5Tget_array_dims_vers ) && H5Tget_array_dims_vers > 1
945 : : (void)perm; /* suppress warning */
946 : 72 : rank = H5Tget_array_dims2( type_id, dims );
947 : : #else
948 : : rank = H5Tget_array_dims( type_id, dims, perm );
949 : : #endif
950 [ - + ]: 72 : if( rank <= 0 )
951 : : {
952 : 0 : mhdf_setFail( status, "H5Tget_size failed." );
953 : 0 : H5Gclose( tag_id );
954 : 0 : H5Tclose( type_id );
955 : 0 : return;
956 : : }
957 [ - + ]: 72 : for( i = 1; i < rank; ++i )
958 : 0 : dims[ 0 ] *= dims[ i ];
959 : :
960 : 72 : super_id = H5Tget_super( type_id );
961 [ - + ]: 72 : if( super_id < 0 )
962 : : {
963 : 0 : mhdf_setFail( status, "H5Tget_super failed" );
964 : 0 : H5Gclose( tag_id );
965 : 0 : H5Tclose( type_id );
966 : 0 : return;
967 : : }
968 : :
969 : 72 : class_tmp = H5Tget_class( super_id );
970 [ - + ]: 72 : if( class_tmp < 0 )
971 : : {
972 : 0 : mhdf_setFail( status, "H5Tget_class failed." );
973 : 0 : H5Gclose( tag_id );
974 : 0 : H5Tclose( type_id );
975 : 0 : H5Tclose( super_id );
976 : 0 : return;
977 : : }
978 : :
979 : 72 : sup_size = H5Tget_size( super_id );
980 : 72 : H5Tclose( super_id );
981 [ - + ]: 72 : if( sup_size <= 0 )
982 : : {
983 : 0 : mhdf_setFail( status, "H5Tget_size failed." );
984 : 0 : H5Gclose( tag_id );
985 : 0 : H5Tclose( type_id );
986 : 0 : return;
987 : : }
988 : :
989 [ + + - ]: 72 : switch( class_tmp )
990 : : {
991 : : case H5T_INTEGER:
992 [ - + ]: 30 : *class_out = ( sup_size == 1 ) ? mhdf_BOOLEAN : mhdf_INTEGER;
993 : 30 : *size_out = dims[ 0 ];
994 : 30 : break;
995 : :
996 : : case H5T_FLOAT:
997 : 42 : *class_out = mhdf_FLOAT;
998 : 42 : *size_out = dims[ 0 ];
999 : 42 : break;
1000 : :
1001 : : default:
1002 : 0 : *class_out = mhdf_OPAQUE;
1003 : 0 : *size_out = size;
1004 : 0 : break;
1005 : : }
1006 : :
1007 : 72 : break;
1008 : : }
1009 : 638 : H5Tclose( type_id );
1010 : 638 : H5Gclose( tag_id );
1011 : :
1012 [ + + ]: 638 : if( is_handle )
1013 : : {
1014 [ - + ]: 79 : if( *class_out != mhdf_INTEGER )
1015 : : {
1016 : 0 : mhdf_setFail( status, "Non-integer tag marked as handle type." );
1017 : 0 : return;
1018 : : }
1019 : 79 : *class_out = mhdf_ENTITY_ID;
1020 : : }
1021 : :
1022 [ + + ]: 638 : if( var_data )
1023 : : {
1024 [ + - ][ - + ]: 82 : if( *size_out != 1 || *class_out == mhdf_BITFIELD )
1025 : : {
1026 : 0 : mhdf_setFail( status, "Invalid or unexpected variable-length tag data" );
1027 : 0 : return;
1028 : : }
1029 : 82 : *size_out = -1;
1030 : : }
1031 : :
1032 : 638 : mhdf_setOkay( status );
1033 : : API_END;
1034 : : }
1035 : :
1036 : 646 : static int read_tag_attrib_data( hid_t tag_id, const char* attrib_name, hid_t type_id, void* data, int is_var_len,
1037 : : mhdf_Status* status )
1038 : : {
1039 : : int rval, ilen;
1040 : : unsigned idx;
1041 : 646 : hid_t read_type = type_id;
1042 : : hsize_t len;
1043 : :
1044 : : /* Check if tag has attribute */
1045 : 646 : rval = mhdf_find_attribute( tag_id, attrib_name, &idx, status );
1046 [ - + ]: 646 : if( rval < 0 )
1047 : 0 : return 0;
1048 [ + + ]: 646 : else if( 0 == rval )
1049 : 21 : return 1;
1050 : :
1051 [ - + ]: 625 : if( NULL == data )
1052 : : {
1053 : 0 : mhdf_setFail( status, "Invalid input." );
1054 : 0 : return 0;
1055 : : }
1056 : :
1057 [ - + ]: 625 : if( is_var_len )
1058 : : {
1059 : : /* len = get_attrib_array_length_index(tag_id, index); */
1060 : 0 : ilen = get_attrib_array_length_name( tag_id, attrib_name );
1061 [ # # ]: 0 : if( ilen < 0 )
1062 : : {
1063 : 0 : mhdf_setFail( status, "Failed to read length of default/mesh value for tag" );
1064 : 0 : return 0;
1065 : : }
1066 : 0 : len = ilen;
1067 : :
1068 : : /* caller passes type_id == 0 for OPAQUE */
1069 [ # # ]: 0 : if( 0 == type_id )
1070 : 0 : read_type = H5Tcreate( H5T_OPAQUE, len );
1071 : : else
1072 : : {
1073 : : #if defined( H5Tarray_create_vers ) && H5Tarray_create_vers > 1
1074 : 0 : read_type = H5Tarray_create2( type_id, 1, &len );
1075 : : #else
1076 : : read_type = H5Tarray_create( type_id, 1, &len, 0 );
1077 : : #endif
1078 : : }
1079 [ # # ]: 0 : if( read_type < 0 )
1080 : : {
1081 : 0 : mhdf_setFail( status, "Failed to read mesh/default value for tag" );
1082 : 0 : return 0;
1083 : : }
1084 : : }
1085 : :
1086 : 625 : rval = mhdf_read_scalar_attrib( tag_id, attrib_name, read_type, data, status );
1087 [ - + ]: 625 : if( is_var_len ) H5Tclose( read_type );
1088 : :
1089 : 646 : return rval;
1090 : : }
1091 : :
1092 : 323 : void mhdf_getTagValues( mhdf_FileHandle file_handle, const char* tag_name, hid_t output_data_type, void* default_value,
1093 : : void* global_value, mhdf_Status* status )
1094 : : {
1095 : : hid_t tag_id;
1096 : : int rval, var_data;
1097 : : unsigned int idx;
1098 : : API_BEGIN;
1099 : :
1100 : : /* check args */
1101 [ + - ][ - + ]: 323 : if( NULL == tag_name || !*tag_name )
1102 : : {
1103 : 0 : mhdf_setFail( status, "Invalid input." );
1104 : 0 : return;
1105 : : }
1106 : :
1107 : : /* Get the tag group */
1108 : 323 : tag_id = get_tag( file_handle, tag_name, NULL, status );
1109 [ - + ]: 323 : if( tag_id < 0 ) return;
1110 : :
1111 : : /* Check for variable-length tag data */
1112 : 323 : rval = mhdf_find_attribute( tag_id, TAG_VARLEN_ATTRIB, &idx, status );
1113 [ - + ]: 323 : if( rval < 0 )
1114 : : {
1115 : 0 : H5Gclose( tag_id );
1116 : 0 : return;
1117 : : }
1118 : 323 : var_data = rval ? 1 : 0;
1119 : :
1120 : : /* Read default value if present */
1121 : 323 : rval = read_tag_attrib_data( tag_id, TAG_DEFAULT_ATTRIB, output_data_type, default_value, var_data, status );
1122 [ - + ]: 323 : if( !rval )
1123 : : {
1124 : 0 : H5Gclose( tag_id );
1125 : 0 : return;
1126 : : }
1127 : :
1128 : : /* Read mesh value if present */
1129 : 323 : rval = read_tag_attrib_data( tag_id, TAG_GLOBAL_ATTRIB, output_data_type, global_value, var_data, status );
1130 [ - + ]: 323 : if( !rval )
1131 : : {
1132 : 0 : H5Gclose( tag_id );
1133 : 0 : return;
1134 : : }
1135 : :
1136 : 323 : H5Gclose( tag_id );
1137 : 323 : mhdf_setOkay( status );
1138 : : API_END;
1139 : : }
1140 : :
1141 : 2366 : int mhdf_haveDenseTag( mhdf_FileHandle file_handle, const char* tag_name, const char* type_handle, mhdf_Status* status )
1142 : : {
1143 : : char* path;
1144 : : hid_t elem_id, group_id;
1145 : : FileHandle* file_ptr;
1146 : 2366 : int rval = 0;
1147 : : API_BEGIN;
1148 : :
1149 : 2366 : file_ptr = (FileHandle*)file_handle;
1150 [ - + ]: 2366 : if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
1151 : :
1152 [ + + ]: 2366 : if( type_handle == mhdf_node_type_handle( ) )
1153 : : {
1154 : : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
1155 : 638 : elem_id = H5Gopen2( file_ptr->hdf_handle, NODE_GROUP, H5P_DEFAULT );
1156 : : #else
1157 : : elem_id = H5Gopen( file_ptr->hdf_handle, NODE_GROUP );
1158 : : #endif
1159 [ - + ]: 638 : if( elem_id < 0 ) mhdf_setFail( status, "Could not open node group." );
1160 : : }
1161 [ + + ]: 1728 : else if( type_handle == mhdf_set_type_handle( ) )
1162 : : {
1163 : : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
1164 : 638 : elem_id = H5Gopen2( file_ptr->hdf_handle, SET_GROUP, H5P_DEFAULT );
1165 : : #else
1166 : : elem_id = H5Gopen( file_ptr->hdf_handle, SET_GROUP );
1167 : : #endif
1168 [ - + ]: 638 : if( elem_id < 0 ) mhdf_setFail( status, "Could not open set group." );
1169 : : }
1170 : : else
1171 : : {
1172 : 1090 : elem_id = mhdf_elem_group_from_handle( file_ptr, type_handle, status );
1173 : : }
1174 [ - + ]: 2366 : if( elem_id < 0 ) return -1;
1175 : :
1176 : 2366 : rval = mhdf_is_in_group( elem_id, TAG_GROUP_NAME, status );
1177 [ - + ]: 2366 : if( rval < 0 )
1178 : : {
1179 : 0 : H5Gclose( elem_id );
1180 : 0 : return -1;
1181 : : }
1182 [ - + ]: 2366 : else if( rval == 0 )
1183 : : {
1184 : 0 : H5Gclose( elem_id );
1185 : 0 : mhdf_setOkay( status );
1186 : 0 : return 0;
1187 : : }
1188 : :
1189 : : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
1190 : 2366 : group_id = H5Gopen2( elem_id, DENSE_TAG_SUBGROUP, H5P_DEFAULT );
1191 : : #else
1192 : : group_id = H5Gopen( elem_id, DENSE_TAG_SUBGROUP );
1193 : : #endif
1194 : 2366 : H5Gclose( elem_id );
1195 [ - + ]: 2366 : if( group_id < 0 )
1196 : : {
1197 : 0 : mhdf_setFail( status, "Could not open tag subgroup." );
1198 : 0 : return -1;
1199 : : }
1200 : :
1201 : 2366 : path = mhdf_name_to_path_copy( tag_name, status );
1202 [ - + ]: 2366 : if( NULL == path )
1203 : : {
1204 : 0 : H5Gclose( group_id );
1205 : 0 : return -1;
1206 : : }
1207 : :
1208 : 2366 : rval = mhdf_is_in_group( group_id, path, status );
1209 : 2366 : H5Gclose( group_id );
1210 : 2366 : free( path );
1211 : :
1212 [ + - ]: 2366 : if( rval >= 0 ) { mhdf_setOkay( status ); }
1213 : :
1214 : : API_END;
1215 : 2366 : return rval;
1216 : : }
1217 : :
1218 : 106 : hid_t mhdf_createDenseTagData( mhdf_FileHandle file_handle, const char* tag_name, const char* type_handle,
1219 : : long num_values, mhdf_Status* status )
1220 : : {
1221 : : char* path;
1222 : : hid_t elem_id, data_id, type_id;
1223 : : FileHandle* file_ptr;
1224 : : size_t name_len, path_len, dir_len;
1225 : : hsize_t size;
1226 : : API_BEGIN;
1227 : :
1228 : 106 : file_ptr = (FileHandle*)file_handle;
1229 [ - + ]: 106 : if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
1230 : :
1231 [ + + ]: 106 : if( type_handle == mhdf_node_type_handle( ) )
1232 : : {
1233 : : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
1234 : 36 : elem_id = H5Gopen2( file_ptr->hdf_handle, NODE_GROUP, H5P_DEFAULT );
1235 : : #else
1236 : : elem_id = H5Gopen( file_ptr->hdf_handle, NODE_GROUP );
1237 : : #endif
1238 [ - + ]: 36 : if( elem_id < 0 ) mhdf_setFail( status, "Could not open node group." );
1239 : : }
1240 [ + + ]: 70 : else if( type_handle == mhdf_set_type_handle( ) )
1241 : : {
1242 : : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
1243 : 32 : elem_id = H5Gopen2( file_ptr->hdf_handle, SET_GROUP, H5P_DEFAULT );
1244 : : #else
1245 : : elem_id = H5Gopen( file_ptr->hdf_handle, SET_GROUP );
1246 : : #endif
1247 [ - + ]: 32 : if( elem_id < 0 ) mhdf_setFail( status, "Could not open set group." );
1248 : : }
1249 : : else
1250 : : {
1251 : 38 : elem_id = mhdf_elem_group_from_handle( file_ptr, type_handle, status );
1252 : : }
1253 [ - + ]: 106 : if( elem_id < 0 ) return -1;
1254 : :
1255 : 106 : dir_len = strlen( DENSE_TAG_SUBGROUP );
1256 : 106 : name_len = mhdf_name_to_path( tag_name, NULL, 0 );
1257 : 106 : path_len = dir_len + name_len + 1;
1258 : 106 : path = (char*)mhdf_malloc( path_len, status );
1259 [ - + ]: 106 : if( NULL == path )
1260 : : {
1261 : 0 : H5Gclose( elem_id );
1262 : 0 : return -1;
1263 : : }
1264 : 106 : strcpy( path, DENSE_TAG_SUBGROUP );
1265 : 106 : mhdf_name_to_path( tag_name, path + dir_len, name_len + 1 );
1266 : :
1267 : 106 : type_id = get_tag_type( file_ptr, path + dir_len, status );
1268 [ - + ]: 106 : if( type_id < 0 )
1269 : : {
1270 : 0 : H5Gclose( elem_id );
1271 : 0 : return -1;
1272 : : }
1273 : :
1274 : 106 : size = (hsize_t)num_values;
1275 : 106 : data_id = mhdf_create_table( elem_id, path, type_id, 1, &size, status );
1276 : 106 : free( path );
1277 : 106 : H5Gclose( elem_id );
1278 : 106 : H5Tclose( type_id );
1279 : :
1280 [ + - ]: 106 : if( data_id > 0 ) mhdf_setOkay( status );
1281 : :
1282 : : API_END_H( 1 );
1283 : 106 : return data_id;
1284 : : }
1285 : :
1286 : 284 : hid_t mhdf_openDenseTagData( mhdf_FileHandle file_handle, const char* tag_name, const char* type_handle,
1287 : : long* num_values_out, mhdf_Status* status )
1288 : : {
1289 : : char* path;
1290 : : hid_t elem_id, data_id;
1291 : : FileHandle* file_ptr;
1292 : : size_t name_len, path_len, dir_len;
1293 : : hsize_t size;
1294 : : API_BEGIN;
1295 : :
1296 : 284 : file_ptr = (FileHandle*)file_handle;
1297 [ - + ]: 284 : if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
1298 : :
1299 [ + + ]: 284 : if( type_handle == mhdf_node_type_handle( ) )
1300 : : {
1301 : : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
1302 : 86 : elem_id = H5Gopen2( file_ptr->hdf_handle, NODE_GROUP, H5P_DEFAULT );
1303 : : #else
1304 : : elem_id = H5Gopen( file_ptr->hdf_handle, NODE_GROUP );
1305 : : #endif
1306 [ - + ]: 86 : if( elem_id < 0 ) mhdf_setFail( status, "Could not open node group." );
1307 : : }
1308 [ + + ]: 198 : else if( type_handle == mhdf_set_type_handle( ) )
1309 : : {
1310 : : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
1311 : 106 : elem_id = H5Gopen2( file_ptr->hdf_handle, SET_GROUP, H5P_DEFAULT );
1312 : : #else
1313 : : elem_id = H5Gopen( file_ptr->hdf_handle, SET_GROUP );
1314 : : #endif
1315 [ - + ]: 106 : if( elem_id < 0 ) mhdf_setFail( status, "Could not open set group." );
1316 : : }
1317 : : else
1318 : : {
1319 : 92 : elem_id = mhdf_elem_group_from_handle( file_ptr, type_handle, status );
1320 : : }
1321 [ - + ]: 284 : if( elem_id < 0 ) return -1;
1322 : :
1323 : 284 : dir_len = strlen( DENSE_TAG_SUBGROUP );
1324 : 284 : name_len = mhdf_name_to_path( tag_name, NULL, 0 );
1325 : 284 : path_len = dir_len + name_len + 1;
1326 : 284 : path = (char*)mhdf_malloc( path_len, status );
1327 [ - + ]: 284 : if( NULL == path )
1328 : : {
1329 : 0 : H5Gclose( elem_id );
1330 : 0 : return -1;
1331 : : }
1332 : 284 : strcpy( path, DENSE_TAG_SUBGROUP );
1333 : 284 : mhdf_name_to_path( tag_name, path + dir_len, name_len + 1 );
1334 : :
1335 : 284 : data_id = mhdf_open_table( elem_id, path, 1, &size, status );
1336 : 284 : free( path );
1337 : 284 : H5Gclose( elem_id );
1338 : 284 : *num_values_out = (long)size;
1339 : :
1340 [ + - ]: 284 : if( data_id >= 0 ) mhdf_setOkay( status );
1341 : :
1342 : : API_END_H( 1 );
1343 : 284 : return data_id;
1344 : : }
1345 : :
1346 : 95 : void mhdf_createSparseTagData( mhdf_FileHandle file_handle, const char* tag_name, long num_values,
1347 : : hid_t handles_out[ 2 ], mhdf_Status* status )
1348 : : {
1349 : : hid_t tag_id, index_id, data_id, type_id, id_type;
1350 : 95 : hsize_t count = (hsize_t)num_values;
1351 : : API_BEGIN;
1352 : :
1353 : 95 : tag_id = get_tag( file_handle, tag_name, &id_type, status );
1354 [ - + ]: 95 : if( tag_id < 0 ) return;
1355 : :
1356 : : #if defined( H5Topen_vers ) && H5Topen_vers > 1
1357 : 95 : type_id = H5Topen2( tag_id, TAG_TYPE_NAME, H5P_DEFAULT );
1358 : : #else
1359 : : type_id = H5Topen( tag_id, TAG_TYPE_NAME );
1360 : : #endif
1361 [ - + ]: 95 : if( type_id < 0 )
1362 : : {
1363 : 0 : H5Gclose( tag_id );
1364 : 0 : mhdf_setFail( status, "Failed to get type object for tag \"%s\".", tag_name );
1365 : 0 : return;
1366 : : }
1367 : :
1368 : 95 : index_id = mhdf_create_table( tag_id, SPARSE_ENTITY_NAME, id_type, 1, &count, status );
1369 [ - + ]: 95 : if( index_id < 0 )
1370 : : {
1371 : 0 : H5Gclose( tag_id );
1372 : 0 : H5Tclose( type_id );
1373 : 0 : return;
1374 : : }
1375 : :
1376 : 95 : data_id = mhdf_create_table( tag_id, SPARSE_VALUES_NAME, type_id, 1, &count, status );
1377 : 95 : H5Tclose( type_id );
1378 : 95 : H5Gclose( tag_id );
1379 [ - + ]: 95 : if( data_id < 0 )
1380 : : {
1381 : 0 : H5Dclose( index_id );
1382 : 0 : return;
1383 : : }
1384 : :
1385 : 95 : handles_out[ 0 ] = index_id;
1386 : 95 : handles_out[ 1 ] = data_id;
1387 : 95 : mhdf_setOkay( status );
1388 : : API_END_H( 2 );
1389 : : }
1390 : :
1391 : 23 : void mhdf_createVarLenTagData( mhdf_FileHandle file_handle, const char* tag_name, long num_entities, long num_values,
1392 : : hid_t handles_out[ 3 ], mhdf_Status* status )
1393 : : {
1394 : : hid_t tag_id, index_id, data_id, type_id, offset_id, id_type;
1395 : 23 : hsize_t count = (hsize_t)num_entities;
1396 : : API_BEGIN;
1397 : :
1398 : 23 : tag_id = get_tag( file_handle, tag_name, &id_type, status );
1399 [ - + ]: 23 : if( tag_id < 0 ) return;
1400 : :
1401 : : #if defined( H5Topen_vers ) && H5Topen_vers > 1
1402 : 23 : type_id = H5Topen2( tag_id, TAG_TYPE_NAME, H5P_DEFAULT );
1403 : : #else
1404 : : type_id = H5Topen( tag_id, TAG_TYPE_NAME );
1405 : : #endif
1406 [ - + ]: 23 : if( type_id < 0 )
1407 : : {
1408 : 0 : H5Gclose( tag_id );
1409 : 0 : mhdf_setFail( status, "Failed to get type object for tag \"%s\".", tag_name );
1410 : 0 : return;
1411 : : }
1412 : :
1413 : 23 : index_id = mhdf_create_table( tag_id, SPARSE_ENTITY_NAME, id_type, 1, &count, status );
1414 [ - + ]: 23 : if( index_id < 0 )
1415 : : {
1416 : 0 : H5Gclose( tag_id );
1417 : 0 : H5Tclose( type_id );
1418 : 0 : return;
1419 : : }
1420 : :
1421 : 23 : offset_id = mhdf_create_table( tag_id, TAG_VAR_INDICES, MHDF_INDEX_TYPE, 1, &count, status );
1422 [ - + ]: 23 : if( index_id < 0 )
1423 : : {
1424 : 0 : H5Dclose( offset_id );
1425 : 0 : H5Gclose( tag_id );
1426 : 0 : H5Tclose( type_id );
1427 : 0 : return;
1428 : : }
1429 : :
1430 : 23 : count = (hsize_t)num_values;
1431 : 23 : data_id = mhdf_create_table( tag_id, SPARSE_VALUES_NAME, type_id, 1, &count, status );
1432 : 23 : H5Tclose( type_id );
1433 : 23 : H5Gclose( tag_id );
1434 [ - + ]: 23 : if( data_id < 0 )
1435 : : {
1436 : 0 : H5Dclose( offset_id );
1437 : 0 : H5Dclose( index_id );
1438 : 0 : return;
1439 : : }
1440 : :
1441 : 23 : handles_out[ 0 ] = index_id;
1442 : 23 : handles_out[ 1 ] = data_id;
1443 : 23 : handles_out[ 2 ] = offset_id;
1444 : 23 : mhdf_setOkay( status );
1445 : : API_END_H( 3 );
1446 : : }
1447 : :
1448 : 361 : void mhdf_openSparseTagData( mhdf_FileHandle file_handle, const char* tag_name, long* num_entity_out,
1449 : : long* num_values_out, hid_t handles_out[ 3 ], mhdf_Status* status )
1450 : : {
1451 : 361 : hid_t tag_id, index_id, data_id, offset_id = -1;
1452 : : hsize_t num_ent, data_size, num_data;
1453 : : int rval;
1454 : : unsigned idx;
1455 : : API_BEGIN;
1456 : :
1457 : 361 : tag_id = get_tag( file_handle, tag_name, NULL, status );
1458 [ - + ]: 361 : if( tag_id < 0 ) return;
1459 : :
1460 : 361 : index_id = mhdf_open_table( tag_id, SPARSE_ENTITY_NAME, 1, &num_ent, status );
1461 [ - + ]: 361 : if( index_id < 0 )
1462 : : {
1463 : 0 : H5Gclose( tag_id );
1464 : 0 : return;
1465 : : }
1466 : :
1467 : 361 : data_id = mhdf_open_table( tag_id, SPARSE_VALUES_NAME, 1, &data_size, status );
1468 [ - + ]: 361 : if( data_id < 0 )
1469 : : {
1470 : 0 : H5Gclose( tag_id );
1471 : 0 : H5Dclose( index_id );
1472 : 0 : return;
1473 : : }
1474 : :
1475 : : /* check if tag is variable-lentgth */
1476 : 361 : rval = mhdf_find_attribute( tag_id, TAG_VARLEN_ATTRIB, &idx, status );
1477 [ - + ]: 361 : if( rval < 0 )
1478 : : {
1479 : 0 : H5Gclose( tag_id );
1480 : 0 : H5Dclose( index_id );
1481 : 0 : H5Dclose( data_id );
1482 : 0 : return;
1483 : : }
1484 : :
1485 : : /* If variable length... */
1486 [ + + ]: 361 : if( rval )
1487 : : {
1488 : 96 : offset_id = mhdf_open_table( tag_id, TAG_VAR_INDICES, 1, &num_data, status );
1489 [ - + ]: 96 : if( offset_id < 0 )
1490 : : {
1491 : 0 : H5Gclose( tag_id );
1492 : 0 : H5Dclose( index_id );
1493 : 0 : H5Dclose( data_id );
1494 : 0 : return;
1495 : : }
1496 : : }
1497 : : /* Otherwise the number of values is the same as the size of the data table */
1498 : : else
1499 : : {
1500 : 265 : num_data = data_size;
1501 : : }
1502 : :
1503 : 361 : H5Gclose( tag_id );
1504 [ - + ]: 361 : if( num_ent != num_data )
1505 : : {
1506 : 0 : mhdf_setFail( status, "Data length mismatch for sparse tag data -- invalid file." );
1507 [ # # ]: 0 : if( offset_id >= 0 ) H5Dclose( offset_id );
1508 : 0 : H5Dclose( index_id );
1509 : 0 : H5Dclose( data_id );
1510 : 0 : return;
1511 : : }
1512 : 361 : *num_entity_out = (long)num_ent;
1513 [ + - ]: 361 : if( num_values_out ) *num_values_out = (long)data_size;
1514 : :
1515 : 361 : handles_out[ 0 ] = index_id;
1516 : 361 : handles_out[ 1 ] = data_id;
1517 [ + + ]: 361 : if( offset_id >= 0 ) handles_out[ 2 ] = offset_id;
1518 : 361 : mhdf_setOkay( status );
1519 : : API_END_H( 2 );
1520 : : }
1521 : :
1522 : 0 : void mhdf_writeSparseTagEntities( hid_t table_id, long offset, long count, hid_t int_type, const void* id_list,
1523 : : mhdf_Status* status )
1524 : : {
1525 : : API_BEGIN;
1526 : 0 : mhdf_write_data( table_id, offset, count, int_type, id_list, H5P_DEFAULT, status );
1527 : : API_END;
1528 : 0 : }
1529 : 118 : void mhdf_writeSparseTagEntitiesWithOpt( hid_t table_id, long offset, long count, hid_t int_type, const void* id_list,
1530 : : hid_t io_prop, mhdf_Status* status )
1531 : : {
1532 : : API_BEGIN;
1533 : 118 : mhdf_write_data( table_id, offset, count, int_type, id_list, io_prop, status );
1534 : : API_END;
1535 : 118 : }
1536 : :
1537 : 0 : void mhdf_writeTagValues( hid_t table_id, long offset, long count, hid_t tag_type, const void* tag_data,
1538 : : mhdf_Status* status )
1539 : : {
1540 : 0 : mhdf_writeTagValuesWithOpt( table_id, offset, count, tag_type, tag_data, H5P_DEFAULT, status );
1541 : 0 : }
1542 : :
1543 : 224 : void mhdf_writeTagValuesWithOpt( hid_t table_id, long offset, long count, hid_t tag_type, const void* tag_data,
1544 : : hid_t io_prop, mhdf_Status* status )
1545 : : {
1546 : : API_BEGIN;
1547 : 224 : mhdf_write_data( table_id, offset, count, tag_type, tag_data, io_prop, status );
1548 : : API_END;
1549 : 224 : }
1550 : :
1551 : 0 : void mhdf_writeSparseTagIndices( hid_t table_id, long offset, long count, hid_t int_type, const void* indices,
1552 : : mhdf_Status* status )
1553 : : {
1554 : : API_BEGIN;
1555 : 0 : mhdf_write_data( table_id, offset, count, int_type, indices, H5P_DEFAULT, status );
1556 : : API_END;
1557 : 0 : }
1558 : 23 : void mhdf_writeSparseTagIndicesWithOpt( hid_t table_id, long offset, long count, hid_t int_type, const void* indices,
1559 : : hid_t io_prop, mhdf_Status* status )
1560 : : {
1561 : : API_BEGIN;
1562 : 23 : mhdf_write_data( table_id, offset, count, int_type, indices, io_prop, status );
1563 : : API_END;
1564 : 23 : }
1565 : :
1566 : 0 : void mhdf_readSparseTagEntities( hid_t table_id, long offset, long count, hid_t int_type, void* id_list,
1567 : : mhdf_Status* status )
1568 : : {
1569 : : API_BEGIN;
1570 : 0 : mhdf_read_data( table_id, offset, count, int_type, id_list, H5P_DEFAULT, status );
1571 : : API_END;
1572 : 0 : }
1573 : 0 : void mhdf_readSparseTagEntitiesWithOpt( hid_t table_id, long offset, long count, hid_t int_type, void* id_list,
1574 : : hid_t io_prop, mhdf_Status* status )
1575 : : {
1576 : : API_BEGIN;
1577 : 0 : mhdf_read_data( table_id, offset, count, int_type, id_list, io_prop, status );
1578 : : API_END;
1579 : 0 : }
1580 : :
1581 : 0 : void mhdf_readTagValues( hid_t table_id, long offset, long count, hid_t tag_type, void* tag_data, mhdf_Status* status )
1582 : : {
1583 : 0 : mhdf_readTagValuesWithOpt( table_id, offset, count, tag_type, tag_data, H5P_DEFAULT, status );
1584 : 0 : }
1585 : 0 : void mhdf_readTagValuesWithOpt( hid_t table_id, long offset, long count, hid_t tag_type, void* tag_data, hid_t io_prop,
1586 : : mhdf_Status* status )
1587 : : {
1588 : : API_BEGIN;
1589 : 0 : mhdf_read_data( table_id, offset, count, tag_type, tag_data, io_prop, status );
1590 : : API_END;
1591 : 0 : }
1592 : :
1593 : 0 : void mhdf_readSparseTagIndices( hid_t table_id, long offset, long count, hid_t int_type, void* indices,
1594 : : mhdf_Status* status )
1595 : : {
1596 : : API_BEGIN;
1597 : 0 : mhdf_read_data( table_id, offset, count, int_type, indices, H5P_DEFAULT, status );
1598 : : API_END;
1599 : 0 : }
1600 : 0 : void mhdf_readSparseTagIndicesWithOpt( hid_t table_id, long offset, long count, hid_t int_type, void* indices,
1601 : : hid_t io_prop, mhdf_Status* status )
1602 : : {
1603 : : API_BEGIN;
1604 : 0 : mhdf_read_data( table_id, offset, count, int_type, indices, io_prop, status );
1605 : : API_END;
1606 : 0 : }
|