TECA
teca_file_util.h
1 #ifndef teca_file_util_h
2 #define teca_file_util_h
3 
4 #include <vector>
5 #include <deque>
6 #include <string>
7 #include <iostream>
8 #include <fstream>
9 #include <sstream>
10 #include <sys/stat.h>
11 
12 class teca_binary_stream;
13 
14 #ifndef WIN32
15  #define PATH_SEP "/"
16 #else
17  #define PATH_SEP "\\"
18 #endif
19 
20 namespace teca_file_util
21 {
22 // read the file into a stream. if header is not null the call will fail if the
23 // given string is not found. return zero upon success. The verbose flag
24 // indicates whether or not an error is reported if opening the file fails. All
25 // other errors are always reported.
26 int read_stream(const char *file_name, const char *header,
27  teca_binary_stream &stream, bool verbose=true);
28 
29 // write the stream to the file. the passed in flags control file access, a
30 // reasonable value is S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH. if header is not null
31 // the given string is prepended to the file. return zero upon success. The
32 // verbose flag indicates whether or not an error is reported if creating the
33 // file fails. All other errors are reported.
34 int write_stream(const char *file_name, int flags, const char *header,
35  const teca_binary_stream &stream, bool verbose=true);
36 
37 // replace %t% with the given value
38 void replace_timestep(std::string &file_name, unsigned long time_step, int width = 6);
39 
40 // replace %t% with the time t in calendar with units in the strftime format
41 int replace_time(std::string &file_name, double t,
42  const std::string &calendar, const std::string &units,
43  const std::string &format);
44 
45 // replace %e% with the given string
46 void replace_extension(std::string &file_name, const std::string &ext);
47 
48 // replace %s% with the given string
49 void replace_identifier(std::string &file_name, const std::string &id);
50 
51 // return string converted to lower case
52 void to_lower(std::string &in);
53 
54 // return 0 if the file does not exist
55 int file_exists(const char *path);
56 
57 // return 0 if the file/directory is not writeable
58 int file_writable(const char *path);
59 
60 // Returns the path not including the file name and not
61 // including the final PATH_SEP. If PATH_SEP isn't found
62 // then ".PATH_SEP" is returned.
63 std::string path(const std::string &filename);
64 
65 // Returns the file name not including the extension (ie what ever is after
66 // the last ".". If there is no "." then the filename is returned unmodified.
67 std::string base_filename(const std::string &filename);
68 
69 // Returns the file name from the given path. If PATH_SEP isn't found
70 // then the filename is returned unmodified.
71 std::string filename(const std::string &filename);
72 
73 // Returns the extension from the given filename.
74 std::string extension(const std::string &filename);
75 
76 // read the lines of the ascii file into a vector
77 size_t load_lines(const char *filename, std::vector<std::string> &lines);
78 
79 // read the file into a string
80 size_t load_text(const std::string &filename, std::string &text);
81 
82 // write the string to the named file
83 int write_text(std::string &filename, std::string &text);
84 
85 int search_and_replace(
86  const std::string &search_for,
87  const std::string &replace_with,
88  std::string &in_text);
89 
90 int locate_files(
91  const std::string &path,
92  const std::string &re,
93  std::vector<std::string> &file_list);
94 
95 //*****************************************************************************
96 template<typename T>
97 size_t load_bin(const char *filename, size_t dlen, T *buffer)
98 {
99  std::ifstream file(filename,std::ios::binary);
100  if (!file.is_open())
101  {
102  std::cerr << "ERROR: File " << filename << " could not be opened." << std::endl;
103  return 0;
104  }
105 
106  // determine file size
107  file.seekg(0,std::ios::end);
108  size_t flen=file.tellg();
109  file.seekg(0,std::ios::beg);
110 
111  // check if file size matches expected read size.
112  if (dlen*sizeof(T)!=flen)
113  {
114  std::cerr
115  << "ERROR: Expected " << dlen << " bytes but found "
116  << flen << " bytes in \"" << filename << "\".";
117  return 0;
118  }
119 
120  // read
121  file.read((char*)buffer,flen);
122  file.close();
123 
124  // return the data, it's up to the caller to free.
125  return dlen;
126 }
127 
130 // ****************************************************************************
131 template<typename T>
132 int name_value(std::vector<std::string> &lines, std::string name, T &value)
133 {
134  size_t n_lines=lines.size();
135  for (size_t i=0; i<n_lines; ++i)
136  {
137  std::string tok;
138  std::istringstream is(lines[i]);
139  is >> tok;
140  if (tok==name)
141  {
142  is >> value;
143  return 1;
144  }
145  }
146  return 0;
147 }
148 
156 // ****************************************************************************
157 template <typename T>
158 size_t parse_value(std::string &in,size_t at, std::string key, T &value)
159 {
160  size_t p=in.find(key,at);
161  if (p!=std::string::npos)
162  {
163  size_t n=key.size();
164 
165  // check to make sure match is the whole word
166  if ((p!=0) && isalpha(in[p-1]) && isalpha(in[p+n]))
167  {
168  return std::string::npos;
169  }
170  // convert value
171  const int max_value_len=64;
172  p+=n;
173  std::istringstream valss(in.substr(p,max_value_len));
174 
175  valss >> value;
176  }
177  return p;
178 }
179 
180 // a stack of lines. lines can be popped as they are processed
181 // and the current line number is recorded.
183 {
184  line_buffer() : m_buffer(nullptr), m_line_number(0) {}
185  ~line_buffer() { free(m_buffer); }
186 
187  // read the contents of the file and intitalize the
188  // stack of lines.
189  int initialize(const char *file_name);
190 
191  // check if the stack is not empty
192  operator bool ()
193  {
194  return !m_lines.empty();
195  }
196 
197  // get the line at the top of the stack
198  char *current()
199  {
200  return m_lines.front();
201  }
202 
203  // remove the line at the top of the stack
204  void pop()
205  {
206  m_lines.pop_front();
207  ++m_line_number;
208  }
209 
210  // get the current line number
211  size_t line_number()
212  {
213  return m_line_number;
214  }
215 
216  char *m_buffer;
217  std::deque<char*> m_lines;
218  size_t m_line_number;
219 };
220 
221 };
222 
223 #endif
teca_binary_stream
Definition: teca_binary_stream.h:16
teca_file_util::line_buffer
Definition: teca_file_util.h:183