Blame view

stim/parser/filename.h 13.5 KB
8157c392   David Mayerich   added parser and ...
1
2
3
4
  #ifndef STIM_FILENAME_H

  #define STIM_FILENAME_H

  

  #include <stdio.h>  /* defines FILENAME_MAX */

25d8d20b   David Mayerich   added FFT support...
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  #include <sstream>

  #include <vector>

  #include <algorithm>

  #include <iostream>

  #include <iomanip>

  

  #include <stim/parser/parser.h>

  

  // set OS dependent defines, including:

  //	1) path division character ('/' or '\') used for output only

  //	2) command for getting the current working directory

  //	3) header files for getting the current working directory

  //	4) include BOOST filesystem class if compiling on GCC

  #define STIM_DIV '/'

5cda84ab   David Mayerich   putting pranathi ...
19
  #ifdef _WIN32

f92397d2   David Mayerich   fixed a Win32 bug...
20
  	#include <windows.h>

25d8d20b   David Mayerich   added FFT support...
21
22
23
  	#include <direct.h>

  	#define GetCurrentDir _getcwd

  	#define STIM_FILENAME_DIV '\\'

8157c392   David Mayerich   added parser and ...
24
  #else

25d8d20b   David Mayerich   added FFT support...
25
26
27
28
29
  	#ifdef BOOST_PRECOMPILED

  		#include <boost/filesystem.hpp>

  	#endif

  	#include <unistd.h>

  	#define GetCurrentDir getcwd

8157c392   David Mayerich   added parser and ...
30
31
32
  	#define STIM_FILENAME_DIV '/'

   #endif

  

8157c392   David Mayerich   added parser and ...
33
34
  namespace stim{

  

25d8d20b   David Mayerich   added FFT support...
35
36
37
38
  class filepath{

  protected:

  	std::string _drive;					//drive on which the file is located (used for Windows)

  	std::vector<std::string> _path;		//path for the specified file (list of hierarchical directories)

8157c392   David Mayerich   added parser and ...
39
  

25d8d20b   David Mayerich   added FFT support...
40
41
42
43
44
  	/// replaces win32 dividers with the Linux standard (used internally by default)

  	std::string unix_div(std::string s) {

  		std::replace( s.begin(), s.end(), '\\', '/');

  		return s;

  	}

8157c392   David Mayerich   added parser and ...
45
  

25d8d20b   David Mayerich   added FFT support...
46
47
48
  	/// gets the directory hierarchy for the current working directory

  	static std::string cwd(){

  		char cCurrentPath[FILENAME_MAX];

8157c392   David Mayerich   added parser and ...
49
  

25d8d20b   David Mayerich   added FFT support...
50
51
52
53
  		 if (!GetCurrentDir(cCurrentPath, sizeof(cCurrentPath))){

  			 std::cout<<"ERROR getting current working directory."<<std::endl;

  			 exit(1);

  		 }

8157c392   David Mayerich   added parser and ...
54
  

25d8d20b   David Mayerich   added FFT support...
55
56
57
  		 std::stringstream ss;

  		 ss<<cCurrentPath;

  		 return ss.str();

8157c392   David Mayerich   added parser and ...
58
59
  	}

  

25d8d20b   David Mayerich   added FFT support...
60
61
  	/// convert a relative path to an absolute path

  	void get_absolute(std::string &drive, std::vector<std::string> &absolute, std::vector<std::string> relative){

8157c392   David Mayerich   added parser and ...
62
  

25d8d20b   David Mayerich   added FFT support...
63
  		std::string current = cwd();						//get the current directory as a string

8157c392   David Mayerich   added parser and ...
64
  

25d8d20b   David Mayerich   added FFT support...
65
66
67
  		std::string current_drive;

  		std::vector<std::string> current_dir;

  		parse_path(current_drive, current_dir, current);			//get the current drive and directories

abb832b8   David Mayerich   fixed drive lette...
68
  		drive = current_drive;										//all relative paths have to be relative to the current drive

a11c7efe   David Mayerich   fixed stim::filen...
69
70
71
72
73
74
75
76
77
78
79
80
81
82
  		if (current_dir.size() > 0) {

  

  			// step through each directory in the relative path, adjusting the current directory

  			//		index depending on whether the relative path is specified with '.' or '..'

  			int current_i = (int)current_dir.size() - 1;

  			int relative_i;

  			for (relative_i = 0; relative_i < relative.size(); relative_i++) {

  				if (relative[relative_i] == "..") current_i--;

  				else if (relative[relative_i] != ".") break;

  			}

  			if (current_i < 0) {

  				std::cerr << "ERROR stim::filepath - relative path is incompatible with working directory" << std::endl;

  				exit(1);

  			}

8b7be670   David Mayerich   implemented savin...
83
  

a11c7efe   David Mayerich   fixed stim::filen...
84
85
86
87
88
89
90
  			absolute.clear();

  			for (size_t i = 0; i <= current_i; i++) {

  				absolute.push_back(current_dir[i]);

  			}

  			for (size_t i = relative_i; i < relative.size(); i++) {

  				absolute.push_back(relative[i]);

  			}

8157c392   David Mayerich   added parser and ...
91
  		}

d64fa68d   David Mayerich   implemented raw s...
92
93
94
  		else {

  			if (relative[0] == ".")

  				relative = std::vector<std::string>(relative.begin() + 1, relative.end());

95f1e985   David Mayerich   updated structure...
95
  			absolute = relative;

d64fa68d   David Mayerich   implemented raw s...
96
  		}

8157c392   David Mayerich   added parser and ...
97
98
  	}

  

25d8d20b   David Mayerich   added FFT support...
99
  	/// Parses a directory string into a drive (NULL if not Windows) and list of hierarchical directories

25d8d20b   David Mayerich   added FFT support...
100
  	void parse_path(std::string &drive, std::vector<std::string> &absolute, std::string dir){

a11c7efe   David Mayerich   fixed stim::filen...
101
  		drive = "";											//initialize the drive to NULL (it will stay that way for Windows)

25d8d20b   David Mayerich   added FFT support...
102
  		std::vector<std::string> path;

a11c7efe   David Mayerich   fixed stim::filen...
103
  		bool relative = true;								//the default path is relative

25d8d20b   David Mayerich   added FFT support...
104
  

a11c7efe   David Mayerich   fixed stim::filen...
105
  		if(dir.length() == 0) return;						//return if the file locator is empty

25d8d20b   David Mayerich   added FFT support...
106
107
108
109
  		std::string unix_dir = unix_div(dir);				//replace any Windows division characters with Unix

  

  		if(unix_dir.length() > 1 && unix_dir[1] == ':'){	//if a drive identifier is given

  			if(unix_dir[0] > 64 && unix_dir[0] < 91)		//if the drive letter is upper case

a11c7efe   David Mayerich   fixed stim::filen...
110
  				drive = unix_dir[0] + 32;					//convert it to lower case

25d8d20b   David Mayerich   added FFT support...
111
  			else if(unix_dir[0] > 96 && unix_dir[0] < 123)	//if the drive character is lower case

a11c7efe   David Mayerich   fixed stim::filen...
112
  				drive = unix_dir[0];					//store it as-is

25d8d20b   David Mayerich   added FFT support...
113
114
115
  			else{											//otherwise throw an error

  				std::cerr<<"ERROR stim::filename - drive letter is invalid: "<<unix_dir[0]<<std::endl;

  				exit(1);

8b7be670   David Mayerich   implemented savin...
116
  			}

25d8d20b   David Mayerich   added FFT support...
117
118
  			unix_dir = unix_dir.substr(2, unix_dir.length()-2);	//extract the directory structure

  		}

8157c392   David Mayerich   added parser and ...
119
  

1c994463   David Mayerich   fixed root direct...
120
121
122
  		if(drive.size() != 0){

  			relative = false;

  		}

a11c7efe   David Mayerich   fixed stim::filen...
123
124
  		if (unix_dir.size() > 0) {										//if there is a directory specified, remove surrounding slashes

  			if (unix_dir[0] == '/') {						//if there is a leading slash

1c994463   David Mayerich   fixed root direct...
125
126
127
  				relative = false;								//the path is not relative

  				unix_dir = unix_dir.substr(1, unix_dir.length() - 1);	//remove the slash

  			}

a11c7efe   David Mayerich   fixed stim::filen...
128
129
  		}

  		if(unix_dir.size() > 0){

1c994463   David Mayerich   fixed root direct...
130
131
  			if(unix_dir[unix_dir.size()-1] == '/')

  				unix_dir = unix_dir.substr(0, unix_dir.length() - 1);

25d8d20b   David Mayerich   added FFT support...
132
  		}

8157c392   David Mayerich   added parser and ...
133
  

25d8d20b   David Mayerich   added FFT support...
134
135
136
137
138
139
  		path = stim::parser::split(unix_dir, '/');					//split up the directory structure

  		

  		if(relative)

  			get_absolute(drive, absolute, path);

  		else

  			absolute = path;

8157c392   David Mayerich   added parser and ...
140
141
  	}

  

25d8d20b   David Mayerich   added FFT support...
142
  	

8157c392   David Mayerich   added parser and ...
143
  

25d8d20b   David Mayerich   added FFT support...
144
145
146
  public:

  	filepath(){

  		_drive = "";

8157c392   David Mayerich   added parser and ...
147
148
  	}

  

25d8d20b   David Mayerich   added FFT support...
149
150
  	filepath(const stim::filepath& p){

  		*this = p;

8157c392   David Mayerich   added parser and ...
151
152
  	}

  

25d8d20b   David Mayerich   added FFT support...
153
154
155
  	filepath(const std::string s){

  		parse_path(_drive, _path, s);

  	}

8157c392   David Mayerich   added parser and ...
156
  

25d8d20b   David Mayerich   added FFT support...
157
158
159
  	stim::filepath& operator=(const std::string s){

  		parse_path(_drive, _path, s);		//parse the string to get the drive and relative path

  		return *this;

8157c392   David Mayerich   added parser and ...
160
161
  	}

  

25d8d20b   David Mayerich   added FFT support...
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
  	std::string str(){

  		std::stringstream ss;

  		if(_drive != "")							//if a drive letter is specified

  			ss<<_drive<<":";						//add it to the string

  		for(size_t i = 0; i < _path.size(); i++)

  			ss<<STIM_FILENAME_DIV<<_path[i];

  		ss<<STIM_FILENAME_DIV;

  		return ss.str();

  	}	

  };				//end filepath

  

  class filename : public filepath{

  protected:

  	std::string _prefix;				//filename prefix

  	std::string _extension;				//filename extension

  

  	void set_filename(std::string fname){

  		size_t ext_i = fname.find_last_of('.');								//calculate the index of the '.'

  		if(ext_i != std::string::npos){											//if there is an extension

  			_prefix = fname.substr(0, ext_i);				//store the prefix

  			_extension = fname.substr(ext_i + 1, fname.size() - ext_i - 1);	//store the extension

  		}

  		else												//otherwise just store the prefix

  			_prefix = fname;

8157c392   David Mayerich   added parser and ...
186
187
  	}

  

25d8d20b   David Mayerich   added FFT support...
188
189
190
191
192
  public:

  	filename(){}

  

  	filename(stim::filepath p, std::string fname) : stim::filepath(p){

  		set_filename(fname);

8157c392   David Mayerich   added parser and ...
193
194
  	}

  

25d8d20b   David Mayerich   added FFT support...
195
196
197
  	stim::filename& operator=(const std::string s){

  		std::string unix_s = unix_div(s);					//convert dividers to unix

  		size_t name_i = unix_s.find_last_of('/');		//find the index of the last divider

8157c392   David Mayerich   added parser and ...
198
  

25d8d20b   David Mayerich   added FFT support...
199
200
201
  		if(name_i == std::string::npos){					//if there is no divider, this is just a filename

  			unix_s = "./" + unix_s;							//append a ./ to the beginning so that the working directory is used

  			name_i = 1;

8b7be670   David Mayerich   implemented savin...
202
  		}

8157c392   David Mayerich   added parser and ...
203
  

25d8d20b   David Mayerich   added FFT support...
204
  		name_i++;

8157c392   David Mayerich   added parser and ...
205
  

8157c392   David Mayerich   added parser and ...
206
  

25d8d20b   David Mayerich   added FFT support...
207
208
209
210
211
212
213
  		std::string filename = unix_s.substr(name_i, unix_s.size() - name_i);	//extract the filename

  		std::string filepath = unix_s.substr(0, name_i-1);						//extract the filepath

  

  		filepath::operator=(filepath);						//parse and store the file path

  

  		set_filename(filename);

  		return *this;

8157c392   David Mayerich   added parser and ...
214
215
  	}

  

25d8d20b   David Mayerich   added FFT support...
216
217
  	filename(std::string s){

  		operator=(s);

6422f96a   Pavel Govyadinov   minor bug fixes a...
218
219
  	}

  

7ada0a48   Pavel Govyadinov   fixed the bugs wi...
220
221
222
  	bool is_relative(){

  		return false;

  	}

25d8d20b   David Mayerich   added FFT support...
223
224
  

  

8157c392   David Mayerich   added parser and ...
225
  	std::string str(){

25d8d20b   David Mayerich   added FFT support...
226
227
228
229
230
  		std::stringstream ss;

  		ss<<filepath::str()<<_prefix;

  		if(_extension.size() != 0)

  			ss<<"."<<_extension;

  		return ss.str();

8157c392   David Mayerich   added parser and ...
231
  	}

4191c034   Pavel Govyadinov   minor:bug fixes. ...
232
  

ec722ff9   David Mayerich   added spero mosai...
233
234
235
236
237
238
239
  	//return a string for the filename without an extension

  	std::string str_noext(){

  		std::stringstream ss;

  		ss<<filepath::str()<<_prefix;

  		return ss.str();

  	}

  

25d8d20b   David Mayerich   added FFT support...
240
  	/// Create a matching file locator with a prefix s

6a53ac0c   David Mayerich   updated optics fi...
241
  	stim::filename with_prefix(std::string s){

25d8d20b   David Mayerich   added FFT support...
242
243
244
245
  		stim::filename result = *this;

  		result._prefix = s;

  		return result;

  	}

8157c392   David Mayerich   added parser and ...
246
  

25d8d20b   David Mayerich   added FFT support...
247
248
249
  	std::string prefix(){

  		return _prefix;

  	}

8157c392   David Mayerich   added parser and ...
250
  

25d8d20b   David Mayerich   added FFT support...
251
252
253
  	std::string get_prefix(){

  		return _prefix;

  	}

eb5dfb2b   David Mayerich   fixed linux compa...
254
  

25d8d20b   David Mayerich   added FFT support...
255
256
257
258
259
260
  	/// Create a matching file locator with the extension changed to s

  	stim::filename extension(std::string s){

  		stim::filename result = *this;

  		result._extension = s;

  		return result;

  	}

8157c392   David Mayerich   added parser and ...
261
  

25d8d20b   David Mayerich   added FFT support...
262
263
264
  	std::string extension(){

  		return _extension;

  	}

8157c392   David Mayerich   added parser and ...
265
  

25d8d20b   David Mayerich   added FFT support...
266
267
268
269
270
271
272
273
274
275
  	stim::filename fname(std::string s){

  		stim::filename result = *this;

  		size_t ext_i = s.find_last_of('.');								//calculate the index of the '.'

  		if(ext_i != std::string::npos){											//if there is an extension

  			result._prefix = s.substr(0, ext_i);				//store the prefix

  			result._extension = s.substr(ext_i + 1, s.size() - ext_i - 1);	//store the extension

  		}

  		else												//otherwise just store the prefix

  			result._prefix = s;

  		return result;

945ee13c   Laila Saadatifard   the get_list func...
276
  	}

eb5dfb2b   David Mayerich   fixed linux compa...
277
  

a11c7efe   David Mayerich   fixed stim::filen...
278
279
280
281
282
283
284
  	std::string fname(){

  		std::string result = prefix();

  		result += ".";

  		result += extension();

  		return result;

  	}

  

25d8d20b   David Mayerich   added FFT support...
285
286
287
288
289
290
  	/// create a matching file locator with the path changed to s

  	stim::filename path(std::string s){

  		stim::filename result = *this;

  		result.parse_path(result._drive, result._path, s);

  		return result;

  	}

8157c392   David Mayerich   added parser and ...
291
  

25d8d20b   David Mayerich   added FFT support...
292
293
294
  	std::string path(){

  		return filepath::str();

  	}

8157c392   David Mayerich   added parser and ...
295
  

25d8d20b   David Mayerich   added FFT support...
296
297
298
299
  	/// Casting operator, casts to a string

  	operator std::string(){

  		return str();

  	}

8157c392   David Mayerich   added parser and ...
300
  

25d8d20b   David Mayerich   added FFT support...
301
302
  	/// This function replaces a wildcard in the prefix with the specified string

  	stim::filename insert(std::string str){

8157c392   David Mayerich   added parser and ...
303
  

25d8d20b   David Mayerich   added FFT support...
304
305
306
307
308
309
310
311
312
313
314
  		stim::filename result = *this;				//initialize the result filename to the current filename

  		size_t loc = result._prefix.find('*');		//find a wild card in the string

  		if(loc == std::string::npos)						//if a wildcard isn't found

  			result._prefix += str;							//append the value to the prefix

  		else

  			result._prefix.replace(loc, 1, str);			//replace the wildcard with the string

  		return result;								//return the result

  	}

  

  	/// This function replaces a wildcard in the prefix with the specified integer (with a padding of n)

  	stim::filename insert(size_t i, size_t n = 2){

8157c392   David Mayerich   added parser and ...
315
  

25d8d20b   David Mayerich   added FFT support...
316
317
318
  		std::stringstream ss;

  		ss << std::setw(n) << std::setfill('0') << i;

  		return insert(ss.str());

945ee13c   Laila Saadatifard   the get_list func...
319
  	}

8157c392   David Mayerich   added parser and ...
320
  

cfcf8619   David Mayerich   changes to filena...
321
322
323
324
325
326
327
328
329
  	///This method returns true if any characters in the filename contain '*' or '?'

  	bool wildcards() {

  		if (_prefix.find('*') != std::string::npos) return true;

  		if (_prefix.find('?') != std::string::npos) return true;

  		if (_extension.find('*') != std::string::npos) return true;

  		if (_extension.find('?') != std::string::npos) return true;

  		return false;

  	}

  

25d8d20b   David Mayerich   added FFT support...
330
  	

4f007f77   David Mayerich   added better comm...
331
332
333
334
  	/// Returns a list of files using the current filename as a template.

  	/// For example:

  	///			C:\this\is\a\path\file*.txt

  	///		can be used as a template to find a series of files file001.txt, file002.txt, file003.txt, etc.

eb5dfb2b   David Mayerich   fixed linux compa...
335
  	std::vector<stim::filename> get_list(){

4f007f77   David Mayerich   added better comm...
336
337
  		//this is OS dependent, so we're starting with Windows

  		//the Unix version requires Boost

8157c392   David Mayerich   added parser and ...
338
  

6d242237   David Mayerich   added comments an...
339
  #ifdef _WIN32

f28202b1   David Mayerich   fixed OS interop ...
340
  

4f007f77   David Mayerich   added better comm...
341
  		HANDLE            hFind = INVALID_HANDLE_VALUE;							//allocate data structures for looping through files

945ee13c   Laila Saadatifard   the get_list func...
342
  		WIN32_FIND_DATAA   FindFileData;

4f007f77   David Mayerich   added better comm...
343
  		std::vector<stim::filename> file_list;									//initialize a list to hold all matching filenames

eb5dfb2b   David Mayerich   fixed linux compa...
344
  

25d8d20b   David Mayerich   added FFT support...
345
346
  		std::string path_string = str();

  		hFind = FindFirstFileA(path_string.c_str(), &FindFileData);		//find the first file that matches the specified file path

945ee13c   Laila Saadatifard   the get_list func...
347
  

4f007f77   David Mayerich   added better comm...
348
  		if (hFind == INVALID_HANDLE_VALUE) { 									//if there are no matching files

25d8d20b   David Mayerich   added FFT support...
349
350
  			//printf ("Invalid file handle. Error is %u.\n", GetLastError());		//print an error

  			return file_list;

eb5dfb2b   David Mayerich   fixed linux compa...
351
  		}

945ee13c   Laila Saadatifard   the get_list func...
352
  		else {

4f007f77   David Mayerich   added better comm...
353
  			std::string file_name = FindFileData.cFileName;						//save the file name

25d8d20b   David Mayerich   added FFT support...
354
  			std::string file_path = path();										//the file is in the specified directory, so save it

4f007f77   David Mayerich   added better comm...
355
  			stim::filename current_file(file_path + file_name);					//create a stim::filename structure representing this file

25d8d20b   David Mayerich   added FFT support...
356
357
358
  			if(!(FindFileData.cFileName[0] == '.' && FindFileData.cFileName[1] == '\0'))

  				file_list.push_back(current_file);									//push the new stim::filename to the file list

  

945ee13c   Laila Saadatifard   the get_list func...
359
360
  

  			// List all the other files in the directory.

4f007f77   David Mayerich   added better comm...
361
  			while (FindNextFileA(hFind, &FindFileData) != 0){ 					//iterate until there are no more matching files

25d8d20b   David Mayerich   added FFT support...
362
363
364
365
366
  				if(!(FindFileData.cFileName[0] == '.' && FindFileData.cFileName[1] == '.' && FindFileData.cFileName[2] == '\0')){	//account for the possibility of the '..' filename

  					file_name = FindFileData.cFileName;								//save the next file

  					current_file = fname(file_name);								//append the directory

  					file_list.push_back(current_file);								//push it to the list

  				}

8157c392   David Mayerich   added parser and ...
367
  			}

4f007f77   David Mayerich   added better comm...
368
  			FindClose(hFind);													//close the file data structure

43dec788   David Mayerich   added code for si...
369
  		}

4f007f77   David Mayerich   added better comm...
370
  		return file_list;														//return the list of files

4e2809fa   David Mayerich   fixed an error pr...
371
372
  

  #elif BOOST_PRECOMPILED

9b766f1f   Pavel Govyadinov   completed merge f...
373
  

7ada0a48   Pavel Govyadinov   fixed the bugs wi...
374
  		boost::filesystem::path p(path());	//create a path from the current filename

9b766f1f   Pavel Govyadinov   completed merge f...
375
376
377
378
379
380
381
382
383
384
385
386
  		std::vector<stim::filename> file_list;

  		if(boost::filesystem::exists(p)){

  			if(boost::filesystem::is_directory(p)){

  				typedef std::vector<boost::filesystem::path> vec;             // store paths,

  				vec v;                                // so we can sort them later

  				std::copy(boost::filesystem::directory_iterator(p), boost::filesystem::directory_iterator(), back_inserter(v));

  				std::sort(v.begin(), v.end());             // sort, since directory iteration

  				  // is not ordered on some file systems

  				//compare file names to the current template (look for wild cards)

  				for (vec::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it)

  				{

  					//if the filename is a wild card *or* it matches the read file name

7ada0a48   Pavel Govyadinov   fixed the bugs wi...
387
  					if( _prefix == "*" || _prefix == (*it).filename().stem().string()){

9b766f1f   Pavel Govyadinov   completed merge f...
388
  						//if the extension is a wild card *or* it matches the read file extension

7ada0a48   Pavel Govyadinov   fixed the bugs wi...
389
  						if( _extension == "*" || "." + _extension == (*it).filename().extension().string()){

9b766f1f   Pavel Govyadinov   completed merge f...
390
391
392
393
394
395
396
397
398
399
400
  							file_list.push_back((*it).string());	//include it in the final list

  						}

  

  					}

  

  

  

  				}

  

  			}

  

84bae1ab   David Mayerich   fixed an error pr...
401
402
  		}

  		return file_list;

4e2809fa   David Mayerich   fixed an error pr...
403
404
405
  #else

  		std::cout<<"ERROR: UNIX systems don't support file lists without the Boost precompiled libraries."<<std::endl;

  		exit(1);

788862df   Tianshu Cheng   added a BOOST_PRE...
406
  #endif

84bae1ab   David Mayerich   fixed an error pr...
407
  		

eb5dfb2b   David Mayerich   fixed linux compa...
408
  	}

25d8d20b   David Mayerich   added FFT support...
409
410
  };				//end filename

  }				//end namespace stim

7ada0a48   Pavel Govyadinov   fixed the bugs wi...
411
  #endif