#include #include typedef struct shared_obj_t{ unsigned long objno[2]; char objname[1024]; int objflag; } shared_obj_t; typedef struct table_t{ int size; int nobjs; shared_obj_t *objs; } table_t; int prefix_len = 1024; char *prefix; table_t group_table, dset_table, type_table; typedef herr_t (*H5G_operator_t)(hid_t, const char*, void*); extern void init_table(void); extern void free_table(void); extern int search_obj (table_t, unsigned long *); extern void add_obj (table_t *, unsigned long *, char *); extern void dump_tables(void); extern herr_t find_shared_objs(hid_t , char *, void *); extern herr_t H5findobj_once(hid_t , char *, void *); extern int get_table_idx(int, unsigned long *); extern int get_tableflag(int, int); extern int set_tableflag(int, int); extern char* get_objectname(int, int); /*------------------------------------------------------------------------- * Function: init_table * * Purpose: allocate and initialize tables for shared groups, datasets, * and committed types * * Return: void * * Programmer: Ruey-Hsia Li * * Modifications: * *-----------------------------------------------------------------------*/ void init_table (void){ int i; group_table.size = dset_table.size = type_table.size = 20; group_table.nobjs = dset_table.nobjs = type_table.nobjs = 0; group_table.objs = (shared_obj_t*) HDmalloc(group_table.size*sizeof(shared_obj_t)); dset_table.objs = (shared_obj_t*) HDmalloc(dset_table.size*sizeof(shared_obj_t)); type_table.objs = (shared_obj_t*) HDmalloc(type_table.size*sizeof(shared_obj_t)); for (i = 0; i < group_table.size; i++) { group_table.objs[i].objno[0] = group_table.objs[i].objno[1] = 0; group_table.objs[i].objflag = 0; } for (i = 0; i < dset_table.size; i++) { dset_table.objs[i].objno[0] = dset_table.objs[i].objno[1] = 0; dset_table.objs[i].objflag = 0; } for (i = 0; i < type_table.size; i++) { dset_table.objs[i].objno[0] = dset_table.objs[i].objno[1] = 0; dset_table.objs[i].objflag = 0; } prefix = (char *) HDmalloc(prefix_len * sizeof (char)); strcpy(prefix, ""); } /*------------------------------------------------------------------------- * Function: free_table * * Purpose: free tables for shared groups, datasets, * and committed types * * Return: void * * Programmer: Paul Harten * * Modifications: * *-----------------------------------------------------------------------*/ void free_table (void){ if (group_table.objs != NULL) { HDfree(group_table.objs); } if (dset_table.objs != NULL) { HDfree(dset_table.objs); } if (type_table.objs != NULL) { HDfree(type_table.objs); } } /*------------------------------------------------------------------------- * Function: search_obj * * Purpose: search the object specified by objno in the table * * Return: an integer, the location of the object * -1 if object is not found * * * Programmer: Ruey-Hsia Li * * Modifications: * *-----------------------------------------------------------------------*/ int search_obj (table_t table, unsigned long *objno) { int i=0, found=0; while (i < table.nobjs && !found) if (table.objs[i].objno[0] == *(objno) && table.objs[i].objno[1] == *(objno+1) ) found = 1; else i++; if (!found) return -1; else return i; } /*------------------------------------------------------------------------- * Function: add_obj * * Purpose: add a shared object to the table * realloc the table if necessary * * Return: void * * Programmer: Ruey-Hsia Li * * Modifications: * *-----------------------------------------------------------------------*/ void add_obj (table_t *table, unsigned long *objno, char *objname) { int i; if (table->nobjs == table->size) { table->size *= 2; table->objs = HDrealloc (table->objs, table->size*sizeof(shared_obj_t)); for (i = table->nobjs; i < table->size; i++) { table->objs[i].objno[0] = table->objs[i].objno[1] = 0; table->objs[i].objflag = 0; } } i = table->nobjs++; table->objs[i].objno[0] = *objno; table->objs[i].objno[1] = *(objno+1); strcpy (table->objs[i].objname, objname); } /*------------------------------------------------------------------------- * Function: dump_tables * * Purpose: display the contents of tables for debugging purposes * * Return: void * * Programmer: Ruey-Hsia Li * * Modifications: * *-----------------------------------------------------------------------*/ void dump_tables(void) { int i; printf("group_table: # of entries = %d\n", group_table.nobjs); for ( i = 0; i < group_table.nobjs; i++) printf ("%lu %lu %s %d\n", group_table.objs[i].objno[0], group_table.objs[i].objno[1], group_table.objs[i].objname, group_table.objs[i].objflag); printf("\ndset_table: # of entries = %d\n", dset_table.nobjs); for ( i = 0; i < dset_table.nobjs; i++) printf ("%lu %lu %s %d\n", dset_table.objs[i].objno[0], dset_table.objs[i].objno[1], dset_table.objs[i].objname, dset_table.objs[i].objflag); printf("\ntype_table: # of entries = %d\n", type_table.nobjs); for ( i = 0; i < type_table.nobjs; i++) printf ("%lu %lu %s %d\n", type_table.objs[i].objno[0], type_table.objs[i].objno[1], type_table.objs[i].objname, type_table.objs[i].objflag); } /*------------------------------------------------------------------------- * Function: Find_shared_objs * * Purpose: Find shared objects, committed types and store them in tables * * Return: Success: SUCCEED * * Failure: FAIL * * Programmer: Ruey-Hsia Li * * Modifications: Paul Harten * *-----------------------------------------------------------------------*/ herr_t find_shared_objs(hid_t group, char *name, void UNUSED *op_data) { hid_t obj, type; H5G_stat_t statbuf; char *tmp; int status=SUCCEED; int i; H5Gget_objinfo(group, name, TRUE, &statbuf); tmp = (char *) HDmalloc ((strlen(prefix)+strlen(name)+2) * sizeof(char)); strcpy(tmp, prefix); switch (statbuf.type) { case H5G_GROUP: if ((obj=H5Gopen (group, name))>=0) { if (prefix_len < (int)(strlen(prefix) + strlen(name) + 2)) { prefix_len *= 2; prefix = HDrealloc (prefix, prefix_len * sizeof(char)); } strcat(strcat(prefix,"/"), name); if (statbuf.nlink > 1) { if (search_obj (group_table, statbuf.objno) < 0) { add_obj (&group_table, statbuf.objno, prefix); status = H5Giterate (obj, ".", NULL, (H5G_operator_t)find_shared_objs, NULL); } } else status = H5Giterate (obj, ".", NULL, (H5G_operator_t)find_shared_objs, NULL); strcpy(prefix, tmp); H5Gclose (obj); } else status = FAIL; break; case H5G_DATASET: strcat(tmp,"/"); strcat(tmp,name); /* absolute name of the data set */ if (statbuf.nlink > 1 && search_obj (dset_table, statbuf.objno) < 0) add_obj (&dset_table, statbuf.objno, tmp); if ((obj=H5Dopen (group, name))>=0) { type = H5Dget_type (obj); if (H5Tcommitted(type) > 0 ) { H5Gget_objinfo(type, ".", TRUE, &statbuf); if (search_obj (type_table, statbuf.objno) < 0) { add_obj (&type_table, statbuf.objno, tmp) ; type_table.objs[type_table.nobjs-1].objflag = 0; } } H5Tclose(type); H5Dclose (obj); status = SUCCEED; } else status = FAIL; break; case H5G_TYPE: strcat(tmp,"/"); strcat(tmp,name); /* absolute name of the type */ i = search_obj (type_table, statbuf.objno); if (i < 0) { add_obj (&type_table, statbuf.objno, tmp) ; type_table.objs[type_table.nobjs-1].objflag = 1; /* named data type */ } else { strcpy (type_table.objs[i].objname, tmp); type_table.objs[i].objflag = 1; /* named data type */ } status = SUCCEED; break; default: break; } HDfree (tmp); return status; } /*------------------------------------------------------------------------- * Function: H5findobj_once * * Purpose: Find objects only once and store them in tables * * Return: Success: SUCCEED * * Failure: FAIL * * Programmer: Paul Harten * * Modifications: * *-----------------------------------------------------------------------*/ herr_t H5findobj_once(hid_t group, char *name, void UNUSED *op_data) { hid_t obj, type; H5G_stat_t statbuf; char *tmp; int status=SUCCEED; int i; H5Gget_objinfo(group, name, TRUE, &statbuf); tmp = (char *) HDmalloc ((strlen(prefix)+strlen(name)+2) * sizeof(char)); strcpy(tmp, prefix); switch (statbuf.type) { case H5G_GROUP: if ((obj=H5Gopen (group, name))>=0) { if (prefix_len < (int)(strlen(prefix) + strlen(name) + 2)) { prefix_len *= 2; prefix = HDrealloc (prefix, prefix_len * sizeof(char)); } strcat(strcat(prefix,"/"), name); if (search_obj (group_table, statbuf.objno) < 0) { add_obj (&group_table, statbuf.objno, prefix); status = H5Giterate (obj, ".", NULL, (H5G_operator_t)H5findobj_once, NULL); } strcpy(prefix, tmp); H5Gclose (obj); } else status = FAIL; break; case H5G_DATASET: strcat(tmp,"/"); strcat(tmp,name); /* absolute name of the data set */ if (search_obj (dset_table, statbuf.objno) < 0) add_obj (&dset_table, statbuf.objno, tmp); if ((obj=H5Dopen (group, name))>=0) { type = H5Dget_type (obj); if (H5Tcommitted(type) > 0 ) { H5Gget_objinfo(type, ".", TRUE, &statbuf); if (search_obj (type_table, statbuf.objno) < 0) { add_obj (&type_table, statbuf.objno, tmp) ; type_table.objs[type_table.nobjs-1].objflag = 0; } } H5Tclose(type); H5Dclose (obj); status = SUCCEED; } else status = FAIL; break; case H5G_TYPE: strcat(tmp,"/"); strcat(tmp,name); /* absolute name of the type */ i = search_obj (type_table, statbuf.objno); if (i < 0) { add_obj (&type_table, statbuf.objno, tmp) ; type_table.objs[type_table.nobjs-1].objflag = 1; /* named data type */ } else { strcpy (type_table.objs[i].objname, tmp); type_table.objs[i].objflag = 1; /* named data type */ } status = SUCCEED; break; default: break; } HDfree (tmp); return status; } /*------------------------------------------------------------------------- * Function: get_table_idx * * Purpose: Determine if objects are in a link loop * * Return: Success: table index of object detected to be in loop * * Failure: FAIL * * Programmer: Paul Harten * *-----------------------------------------------------------------------*/ int get_table_idx(int type, unsigned long *objno) { int idx; switch (type) { case H5G_GROUP: idx = search_obj(group_table, objno); break; case H5G_DATASET: idx = search_obj(dset_table, objno); break; case H5G_TYPE: idx = search_obj(type_table, objno); break; default: idx = -1; } return idx; } /*------------------------------------------------------------------------- * Function: Get table flag setting * * Purpose: Keep the structures and variables used private to * this file. * * Return: Success: Boolean setting of the i'th element of the * object table flag * * Failure: FAIL * * Programmer: Paul Harten * *-----------------------------------------------------------------------*/ int get_tableflag(int type, int idx) { switch (type) { case H5G_GROUP: return group_table.objs[idx].objflag; case H5G_DATASET: return dset_table.objs[idx].objflag; case H5G_TYPE: return type_table.objs[idx].objflag; default: return -1; } } /*------------------------------------------------------------------------- * Function: Set table flag setting * * Purpose: Keep the structures and variables used private to * this file. * * Return: Success: Boolean setting of the i'th element of the * object table flag * * Failure: FAIL * * Programmer: Paul Harten * *-----------------------------------------------------------------------*/ int set_tableflag(int type, int idx) { switch (type) { case H5G_GROUP: group_table.objs[idx].objflag = TRUE; return SUCCEED; case H5G_DATASET: dset_table.objs[idx].objflag = TRUE; return SUCCEED; case H5G_TYPE: type_table.objs[idx].objflag = TRUE; return SUCCEED; default: return FAIL; } } /*------------------------------------------------------------------------- * Function: Get name of i'th object in table * * Purpose: * * Return: Success: strdup() of object name character string * * Failure: NULL * * Programmer: Paul Harten * *-----------------------------------------------------------------------*/ char * get_objectname(int type, int idx) { switch (type) { case H5G_GROUP: return strdup(group_table.objs[idx].objname); case H5G_DATASET: return strdup(dset_table.objs[idx].objname); case H5G_TYPE: return strdup(type_table.objs[idx].objname); default: return NULL; } }