void datMsg( const char * token, const HDSLoc * loc ) { /* Local Variables: */ char buff[EMS__SZMSG+EMS__SZMSG+2]; /* Buffer for file+path */ char file[EMS__SZMSG+1]; /* Container file name */ char path[EMS__SZMSG+1]; /* Object path name */ char *bra; /* Position of '(' character */ char *dot; /* Position of '.' */ size_t ncf; /* Number of characters in filename */ int nlev; /* Object level in HDS */ #if defined( vms ) char *semi; /* Position of ';' */ #endif char *start; /* Position to start in path name */ int status = DAT__OK; /* local status variable */ int odd; /* Is the filename odd? */ int ok; /* No error occurred? */ /* Mark the error stack */ emsMark(); /* Obtain the data object path and container file name. */ hdsTrace( loc, &nlev, path, file, &status, sizeof(path), sizeof(file) ); if ( status == DAT__OK ) { /* If necessary, handle VAX/VMS file names. Locate the semicolon which * delimits the version number in the file name. */ #if defined( vms ) semi = strchr( file, ';' ); /* If found, then select the file name prior to it by replacing it with a nul. */ if (semi != NULL ) { *semi = '\0'; } #endif /* Find the filename length */ ncf = strlen( file ); /* See if the file is "odd". Check to see if it has the default file * extension of '.SDF' with at least one character preceding it. */ odd = 1; if ( ncf >= 5 ) { if ( strcmp( &file[ncf-DAT__SZFLX], DAT__FLEXT ) == 0) { odd = 0; } else { odd = 1; } } /* If the file name is not odd, then omit the file extension. */ if (!odd) file[ncf-DAT__SZFLX] = '\0'; /* Enter the file name into the buffer, surrounding it in quotes if it * is odd. */ *buff = '\0'; if (odd) strcat(buff, "\"" ); strcat( buff, file ); if (odd) strcat(buff, "\"" ); /* If the object is not a top-level object, then find the position of * the first '.' in its pathname, which marks the start of the first * component name. */ if (nlev > 1 ) { dot = strchr( path, '.' ); /* If successful, see if the '.' is preceded by a '(' indicating that * the top-level object is subscripted. Derive the starting position in * the path name so that the subscript is used if present. */ if (dot != NULL) { bra = strchr( path, '(' ); if (bra != NULL && bra < dot) { start = bra; } else { start = dot; } /* Add the required part of the path name to the buffer. */ strcat( buff, start ); } } else { /* If the object is a top-level object, then see if it is subscripted. * If so, then add the subscript to the buffer. */ start = strchr( path, '(' ); if ( start != NULL ) { strcat( buff, start ); } } } /* Note if any error has occurred. */ ok = ( status == DAT__OK ? 1 : 0 ); /* If an error occurred, then annul it. Release the error stack. */ if ( status != DAT__OK ) emsAnnul( &status ); emsRlse(); /* If no error occurred, then assign the resulting buffer contents to * the message token. */ if (ok) emsSetc( token, buff ); }
hid_t dat1Reopen( hid_t file_id, unsigned int flags, hid_t fapl, int *status ){ /* Local Variables; */ HDSLoc **loc; HDSLoc **loclist; char **paths; char file[EMS__SZMSG+1]; char path[EMS__SZMSG+1]; hid_t *file_ids; hid_t id; int *isgroup; int iloc; int nlev; int nloc; ssize_t size; /* Return immediately if an error has already occurred. */ if( *status != SAI__OK ) return file_id; /* Get a list of any active locators associated with the file. Also get a list of file_ids for the same file that have associated locators. */ hds1GetLocators( file_id, &nloc, &loclist, &file_ids, status ); /* Check that none of the locators are mapped. */ if( *status == SAI__OK ) { loc = loclist; for( iloc = 0; iloc < nloc; iloc++,loc++ ) { if( (*loc)->regpntr ) { hdsTrace( (*loc), &nlev, path, file, status, sizeof(path), sizeof(file) ); *status = DAT__PRMAP; emsRepf( " ", "hdsOpen: Cannot re-open '%s' in read-write mode " "since '%s' is currently mapped.", status, file, path ); break; } } } /* Store the path to the HDF5 object associated with each active locator, and also a flag indicating if the HDF5 object is a group or dataset. Then close the HDF5 objects. */ paths = MEM_CALLOC( nloc, sizeof( *paths ) ); isgroup = MEM_CALLOC( nloc, sizeof( *isgroup ) ); if( paths && isgroup && *status == SAI__OK ) { loc = loclist; for( iloc = 0; iloc < nloc; iloc++,loc++ ) { if( (*loc)->group_id ) { isgroup[ iloc ] = 1; id = (*loc)->group_id; } else { isgroup[ iloc ] = 0; id = (*loc)->dataset_id; } if( id ) { size = H5Iget_name( id, NULL, 0 ); paths[ iloc ] = MEM_CALLOC( size + 1, 1 ); H5Iget_name( id, paths[ iloc ], size + 1 ); } else { hdsTrace( (*loc), &nlev, path, file, status, sizeof(path), sizeof(file) ); *status = DAT__FATAL; emsRepf( " ", "hdsOpen: Locator for '%s.%s' has no group or " "dataset so cannot be reopened.", status, file, path ); break; } if( H5Oclose( id ) < 0 ) { hdsTrace( (*loc), &nlev, path, file, status, sizeof(path), sizeof(file) ); *status = DAT__FATAL; dat1H5EtoEMS( status ); emsRepf( " ", "hdsOpen: Failed to close HDF5 object for '%s.%s'.", status, file, path ); break; } } } /* Get the path for the file. */ H5Fget_name( file_id, path, sizeof(path) ); /* Close all HDF5 file_ids associated with file. */ if( *status == SAI__OK ) { int this_closed = 0; int i = -1; while( file_ids[ ++i ] ) { if( file_ids[ i ] == file_id ) this_closed = 1; if( H5Fclose( file_ids[ i ] ) < 0 ) { *status = DAT__FATAL; dat1H5EtoEMS( status ); emsRepf( " ", "hdsOpen: Failed to close file '%s' prior to " "re-opening it.", status, path ); break; } } /* Close the supplied file_id if it has not already been closed. */ if( !this_closed ) { if( H5Fclose( file_id ) < 0 ) { *status = DAT__FATAL; dat1H5EtoEMS( status ); emsRepf( " ", "hdsOpen: Failed to close file '%s' prior to " "re-opening it.", status, path ); } } } /* Re-open it. */ if( *status == SAI__OK ) { file_id = H5Fopen( path, flags, fapl ); if( file_id < 0 ) { *status = DAT__FATAL; dat1H5EtoEMS( status ); emsRepf( " ", "hdsOpen: Failed to reopen file '%s'.", status, path ); } } /* Update the file, group and dataset id in each locator. */ if( *status == SAI__OK ) { loc = loclist; for( iloc = 0; iloc < nloc; iloc++,loc++ ) { hds1SetFileId( (*loc), file_id, status ); if( isgroup[ iloc ] ) { (*loc)->group_id = H5Gopen2( file_id, paths[ iloc ], H5P_DEFAULT ); } else { (*loc)->dataset_id = H5Dopen2( file_id, paths[ iloc ], H5P_DEFAULT ); } } } /* Free resources. */ if( paths ) { for( iloc = 0; iloc < nloc; iloc++ ) { MEM_FREE( paths[ iloc ] ); } MEM_FREE( paths ); } if( isgroup ) MEM_FREE( isgroup ); if( loclist ) MEM_FREE( loclist ); if( file_ids ) MEM_FREE( file_ids ); /* Return the new file id. */ return file_id; }
int datRef( const HDSLoc * locator, char * ref, size_t reflen, int * status ) { /* Local Variables: */ char buff[MAX_PATH_LEN+1]; /* Buffer */ char file[MAX_PATH_LEN+1]; /* Container file name */ char path[MAX_PATH_LEN+1]; /* Object path name */ char *bra; /* Position of '(' character */ char *dot; /* Position of '.' */ size_t ncf; /* Number of characters in filename */ int i; /* Loop counter */ int nlev; /* Object level in HDS */ #if defined( vms ) char *semi; /* Position of ';' */ #endif char *start; /* Position to start in path name */ int add_dot; /* Do we need to add a '.' ? */ int odd; /* Is the filename odd? */ /* Terminate the buffer so that it is safe*/ *ref = '\0'; /* Check intial global status */ if ( *status != DAT__OK ) return *status; /* Obtain the data object path and container file name. */ /* Lie about the size of the supplied buffer to account for quotes and dots that may be added */ hdsTrace( locator, &nlev, path, file, status, MAX_PATH_LEN-3, MAX_PATH_LEN-1 ); if ( *status == DAT__OK ) { /* If necessary, handle VAX/VMS file names. Locate the semicolon which * delimits the version number in the file name. */ #if defined( vms ) semi = strchr( file, ';' ); /* If found, then select the file name prior to it by replacing it with a nul. */ if (semi != NULL ) { *semi = '\0'; } #endif /* Find the filename length */ ncf = strlen( file ); /* See if the file is "odd". Check to see if it has the default file * extension of '.SDF' with at least one character preceding it. */ odd = 1; if ( ncf >= 5 ) { if ( strcmp( &file[ncf-DAT__SZFLX], DAT__FLEXT) == 0) { odd = 0; } else { odd = 1; } } /* If the file name is odd, then we must also decide whether to append * a '.' to the end of it. This is done to counteract the removal of a * terminating '.' which HDS performs on all Unix file names (to permit * the creation of files without a '.' in their names if required). * Initially assume an extra '.' is needed. */ if (odd) { add_dot = 1; /* If the file name already ends with a '.'. then another '.' will be * needed to protect it. Otherwise, search backwards through the final * field of the file name (stopping when a '/' is encountered) to see * whether there is already a '.' present. */ if ( file[ncf-1] != '.' ) { /* search back through the string */ for ( i = 1; i <= ncf ; i++ ) { if ( file[ncf-i] == '/' ) break; /* If a '.' is present, then note that another one need not be added * (otherwise one must be added to prevent the default ".sdf" extension * being appended if HDS re-opens the file using this name). */ if ( file[ncf-i] == '.' ) { add_dot = 0; break; } } /* If an extra '.' is needed, then append it to the file name (note * that an extra character is reserved in FILE for this purpose). */ if (add_dot) { strcat( file, "." ); } } } /* If the file name is not odd, then omit the file extension. */ if (!odd) file[ncf-4] = '\0'; /* Enter the file name into the buffer, surrounding it in quotes if it * is odd. */ *buff = '\0'; if (odd) strcat(buff, "\"" ); strcat( buff, file ); if (odd) strcat(buff, "\"" ); /* If the object is not a top-level object, then find the position of * the first '.' in its pathname, which marks the start of the first * component name. */ if (nlev > 1 ) { dot = strchr( path, '.' ); /* If successful, see if the '.' is preceded by a '(' indicating that * the top-level object is subscripted. Derive the starting position in * the path name so that the subscript is used if present. */ if (dot != NULL) { bra = strchr( path, '(' ); if (bra != NULL && bra < dot) { start = bra; } else { start = dot; } /* Add the required part of the path name to the buffer. */ strcat( buff, start ); } } else { /* If the object is a top-level object, then see if it is subscripted. * If so, then add the subscript to the buffer. */ start = strchr( path, '(' ); if ( start != NULL ) { strcat( buff, start ); } } /* If the length of the reference name exceeded the length of the output * argument, then append an ellipsis. */ if ( strlen(buff) > reflen -1 ) { strncpy( ref, buff, reflen - 4 ); ref[reflen-4] = '\0'; strcat(ref, "xyz"); /* Report an error showing the truncated character string */ *status = DAT__TRUNC; emsSetc( "STRING", ref ); emsRep( "DAT_REF_1", "Character string truncated: '^STRING'.", status ); emsRep( "DAT_REF_2", "Output character variable is too short " "to accommodate the returned result.", status ); } else { strcpy( ref, buff ); } } /* If an error occurred report contextual information */ if ( *status != DAT__OK ) { emsRep( "DAT_REF_ERR", "DAT_REF: Error obtaining a reference name " "for an HDS object.", status ); } return *status; }