00001 // BLAsciiFile.hh 00002 /* 00003 This source file is part of G4beamline, http://g4beamline.muonsinc.com 00004 Copyright (C) 2003,2004,2005,2006 by Tom Roberts, all rights reserved. 00005 00006 This program is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU General Public License 00008 as published by the Free Software Foundation; either version 2 00009 of the License, or (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 http://www.gnu.org/copyleft/gpl.html 00017 */ 00018 00019 #ifndef BLASCIIFILE 00020 #define BLASCIIFILE 00021 00022 #include <map> 00023 #include <set> 00024 #include <stdio.h> 00025 00026 #include "globals.hh" 00027 00028 /** class BLAsciiFile manages file-descriptors for writing ASCII files. 00029 * 00030 * Multiple fopen()-s of a given filename will all get the same FILE *. 00031 * Multiple fclose()-s of the FILE* are handled properly (fhe first 00032 * closes the file, successive ones do nothing). 00033 * 00034 * The filename-s must match exactly as given, no conversion to absolute 00035 * paths (or any other canonicalization) is performed.. 00036 * 00037 * Only does writing. 00038 **/ 00039 class BLAsciiFile { 00040 static std::map<G4String,FILE*> fds; 00041 public: 00042 /// fopen() will open a file for writing, returning the same FILE * 00043 /// for multiple opens. 00044 static FILE *fopen(G4String name) { 00045 if(fds.count(name) == 0) { 00046 FILE *f = ::fopen(name.c_str(),"w"); 00047 if(f != 0) 00048 fds[name] = f; 00049 return f; 00050 } 00051 return fds[name]; 00052 } 00053 00054 /// fclose() will close the FILE*, handling multiple calls. 00055 static void fclose(FILE *f) { 00056 std::map<G4String,FILE*>::iterator i; 00057 for(i=fds.begin(); i!=fds.end(); ++i) { 00058 if(i->second != f) continue; 00059 ::fclose(f); 00060 fds.erase(i); 00061 break; 00062 } 00063 } 00064 }; 00065 00066 #endif // BLASCIIFILE