/** @page fopen IWAVE File Management Functions Interface to standard C i/o. Creates database of filenames and associated FILE*s. ALWAYS use in place of fopen in all iwave apps. Associates file pointers to file names for the life of the process. Since many file types are structured after prototypes, also records prototype information. The fopen interface \ref iwave_fopen searches for file in list of already-opened files for given name, mode, prototype, and temp status, returns pointer assigned to file if found, otherwise opens file and returns file pointer with appropriate mode set. Files are either temp or archival. Temp files treated differently from archival files. Temp files may be re-used or overwritten when current use is finished, for which purpose the database flags temp status. Indicate temp status by setting *name=NULL on call to \ref iwave_fopen - in that case, on (successful) return, reassigns this pointer to a copy of a character string generated by mkstemp. Passing a non-NULL char * indicates archival status of the file - the string passed is the name of the file opened, either in the current call to iwave_fopen or cached in a previous call. In either case, memory allocated for filename storage must be managed by the calling unit. The calling app should NOT close files or reset file pointers. Once opened, files remain open until closed in the "destructor" iwave_fdestroy, which should be called only once on exit from an app process. The utility iwave_fclose marks temporary files for possible re-use, but has no effect on archival files. A temp file marked for re-use by iwave_fclose may be returned for use by another call to iwave_fopen with any access mode. However the access mode will be ignored, as iwave_fopen opens all temp files with access mode "w+". Unlike fopen, the file is truncated only on being opened the first time by iwave_fopen. Subsequent calls which return pointers to the same file (switching from inuse=0 to inuse=1, for temp files) do not truncate the existing file. */ #ifndef __IWAVE_FOPEN__ #define __IWAVE_FOPEN__ #include "utils.h" /** if set, unlink temporary files in iwave_fdestroy */ #define UNLINK_TMPS //#undef UNLINK_TMPS /** Organized to behave exactly as fopen does with respect to mode: ``r'' Open text file for reading. The stream is positioned at the beginning of the file. ``r+'' Open for reading and writing. The stream is positioned at the beginning of the file. ``w'' Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file. ``w+'' Open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file. No use of the "a" modes is expected in IWAVE, though these should also work the same way. @param name pointer to name (char *) of file to be opened. If *name != NULL on call, then used as target filename and treated as const. If NULL on call, then assigned to a string generated by mkstemp, either new if no suitable temp file available, or name of an existing temp file if one with same prototype is not in use, on return. @param mode access mode, exactly as in fopen @param proto name of prototype file - NULL if no prototype exists; if assigned, guarantees that file has same internal structure as prototype. On opening a new file with an existing prototype in w or w+ mode, iwave_fopen performs byte-level copy of prototype onto target, which enforces guarantee. For r or r+ access mode, only file length is checked against prototype, as iwave_fopen has no access to any other information about internal file structure. @param stream verbose output unit @return either valid file pointer, or NULL if none could be found or allocated */ FILE * iwave_fopen(char ** name, const char * mode, const char * proto, FILE * stream); /** const filename version of iwave_fopen. Returns non-null FILE* only if name is non-null string, naming existing file meeting other criteria (for example, matching prototype, if one is given). Arguments, function otherwise identical to iwave_fopen. */ FILE * iwave_const_fopen(const char * name, const char * mode, const char * proto, FILE * stream); /** If file has temp status, flags file as not in use (does not actually close or unlink). Temp files on which iwave_fclose has been called may be reused as out-of-core workspace with the same prototype later in an application. No-op for archival file. */ void iwave_fclose(FILE * fp); /** closes all files, unlinks those flagged as temporary, deallocates all memory allocated in the buildup of the file database. call only once per application, on exit from the application process. */ void iwave_fdestroy(); /** prints the data of the file management struct */ void iwave_fprintall(FILE * stream); /** returns prototype filename for given filename, or NULL if none found */ const char * iwave_getproto(const char * name); #endif