Line data Source code
1 : /*
2 : * Copyright (c) 2012-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Torbjörn Klatt
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 : *
27 : * This program is distributed in the hope that it will be useful,
28 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 : * GNU Lesser General Public License for more details.
31 : */
32 :
33 : /**
34 : * \file file_util.cpp
35 : * \date 2012-05-15
36 : * \brief Implementation of OS independent file utility functions
37 : */
38 :
39 : #include "common/util/file_util.h"
40 : #include "common/ug_config.h"
41 : #include "common/error.h"
42 : #include "common/assert.h"
43 : #include "common/profiler/profiler.h"
44 : #include "path_provider.h"
45 : #include <vector>
46 : #include <cstring>
47 :
48 : using namespace std;
49 :
50 : namespace ug
51 : {
52 : /// !!! Serial i/o version !!!
53 18 : UG_API bool FileExists( const char *filename )
54 : {
55 : PROFILE_FUNC(); // since i/o
56 :
57 18 : ifstream in( filename );
58 18 : if( in.good() ) {
59 17 : in.close();
60 : return true;
61 : }
62 : return false;
63 18 : }
64 :
65 : /// !!! Serial i/o version !!!
66 : // UG_API size_t FileSize( const char *filename )
67 : // {
68 : // PROFILE_FUNC(); // since i/o
69 :
70 : // if( !FileExists( filename ) ) {
71 : // UG_THROW( "The file " << filename << " could not be found." );
72 : // }
73 :
74 : // ifstream ifs;
75 : // ifs.open( filename, ios_base::in );
76 :
77 : // if( !ifs.good() ) {
78 : // UG_THROW( "The file " << filename << " could not be opened." );
79 : // }
80 : // ifs.seekg( 0, ios_base::end );
81 : // size_t length = ifs.tellg();
82 : // ifs.close();
83 : // return length;
84 : // }
85 :
86 0 : bool FileTypeIs( const char* filename, const char* extension )
87 : {
88 : PROFILE_FUNC();
89 0 : std::string name( filename );
90 : size_t iExtPos = name.find_last_of(".");
91 0 : return ( iExtPos != std::string::npos && name.substr(iExtPos).compare(extension) == 0 );
92 : }
93 :
94 : /// !!! Serial i/o version !!!
95 4 : UG_API bool FileCompare( const char *file1, const char *file2 )
96 : {
97 : PROFILE_FUNC(); // since i/o
98 :
99 : // Make sure, both files do exist
100 4 : if( !FileExists( file1 ) || !FileExists( file2 ) ) {
101 0 : UG_THROW( "One or both files could not be found:" << file1 << ", " << file2 );
102 : }
103 :
104 : // If both files are one and the same, we don't need to compare them any more
105 4 : if( strcmp( file1, file2 ) == 0 ) {
106 : return true;
107 : }
108 :
109 : // If the files have different size, we know that they are different and can stop
110 3 : size_t size1 = FileSize( file1 ), size2 = FileSize( file2 );
111 3 : if( size1 != size2 ) {
112 : return false;
113 : }
114 : // If both files have zero size, we can stop as well
115 2 : if( size1 == 0 && size2 == 0 ) {
116 : return true;
117 : }
118 :
119 : // Open the files
120 2 : ifstream f1, f2;
121 2 : f1.open( file1, ios_base::in );
122 2 : f2.open( file2, ios_base::in );
123 :
124 : // This should be obsolete, as it is checked by FileExists, but we want to be
125 : // sure.
126 2 : if( !f1.good() || !f2.good() ) {
127 0 : UG_THROW( "One or both files could not be opened:" << file1 << ", " << file2 );
128 : }
129 :
130 2 : string line1 = "", line2 = "";
131 : bool diff = false;
132 16 : while( !f1.eof() || !f2.eof() ) {
133 15 : getline( f1, line1 );
134 15 : getline( f2, line2 );
135 29 : if( ( line1 != line2 ) ||
136 29 : ( f1.eof() && !f2.eof() ) ||
137 13 : ( !f1.eof() && f2.eof() ) ) {
138 : diff = true;
139 : break;
140 : }
141 : }
142 :
143 2 : f1.close();
144 2 : f2.close();
145 :
146 2 : return !diff;
147 2 : }
148 :
149 : /// !!! Serial i/o version !!!
150 : /// in parallel, see ParallelReadFile.
151 0 : bool ReadFile(const char* filename, vector<char> &file, bool bText)
152 : {
153 : PROFILE_FUNC();
154 :
155 0 : size_t fileSize = FileSize(filename);
156 :
157 0 : FILE *f = fopen(filename, "rb");
158 0 : if(f==NULL) return false;
159 :
160 :
161 0 : if(bText)
162 0 : file.resize(fileSize + 1);
163 : else
164 0 : file.resize(fileSize);
165 :
166 : size_t readSize = fread(&file[0], 1, fileSize, f);
167 0 : UG_COND_THROW(readSize != fileSize,
168 : "Read mismatch in ReadFile. Wrong number of bytes read: "
169 : << readSize << ", expected: " << fileSize);
170 :
171 0 : fclose(f);
172 0 : if(bText) file[fileSize]=0x00;
173 : return true;
174 : }
175 :
176 : /// !!! Serial i/o version !!!
177 0 : string MakeTmpFile(string filename, const string &extension, bool &bSuccess)
178 : {
179 : PROFILE_FUNC(); // since i/o
180 0 : bSuccess = true;
181 : string t = filename+extension;
182 : const char *name = t.c_str();
183 0 : if(!FileExists(name)) return name;
184 0 : for(int i=0;i<999999; i++)
185 : {
186 0 : stringstream ss;
187 0 : ss << filename << i << extension;
188 0 : name = ss.str().c_str();
189 0 : if(!FileExists(name)) return name;
190 0 : }
191 0 : bSuccess = false;
192 0 : return "";
193 : }
194 :
195 : ////////////////////////////////////////////////////////////////////////////////
196 0 : std::string FindFileInStandardPaths(const char* filename)
197 : {
198 : // first check whether the file can be loaded (e.g. absolute path or relative to working-directory)
199 0 : std::string filenameOut = filename;
200 0 : if(FileExists(filenameOut.c_str()))
201 0 : return filenameOut;
202 :
203 : // Now check whether the file was specified relative to the current
204 : // scripting-directory or script or apps or root paths
205 0 : PathProvider::get_filename_relative_to_current_path(filename, filenameOut)
206 0 : || PathProvider::get_filename_relative_to_path(SCRIPT_PATH, filename, filenameOut)
207 0 : || PathProvider::get_filename_relative_to_path(APPS_PATH, filename, filenameOut)
208 0 : || PathProvider::get_filename_relative_to_path(ROOT_PATH, filename, filenameOut);
209 :
210 0 : if(FileExists(filenameOut.c_str()))
211 0 : return filenameOut;
212 :
213 : // filename couldn't be located
214 0 : return "";
215 : }
216 :
217 :
218 0 : std::string FindDirInStandardPaths(const char* dirname)
219 : {
220 : // first check whether the file can be loaded (e.g. absolute path or relative to working directory)
221 0 : std::string dirNameOut = dirname;
222 0 : if (DirectoryExists(dirNameOut.c_str()))
223 0 : return dirNameOut;
224 :
225 : // Now check whether the directory was specified relative to the current
226 : // scripting-directory or script or apps or root paths
227 0 : bool success = PathProvider::get_dirname_relative_to_current_path(dirname, dirNameOut)
228 0 : || PathProvider::get_dirname_relative_to_path(SCRIPT_PATH, dirname, dirNameOut)
229 0 : || PathProvider::get_dirname_relative_to_path(APPS_PATH, dirname, dirNameOut)
230 0 : || PathProvider::get_dirname_relative_to_path(ROOT_PATH, dirname, dirNameOut);
231 :
232 0 : if (success)
233 0 : return dirNameOut;
234 :
235 : // filename couldn't be located
236 0 : return "";
237 : }
238 :
239 :
240 :
241 : } // namespace ug
242 :
243 : // EOF
|