Merge branch 'master' of ssh://repo.or.cz/srv/git/ail
[ail.git] / source / file.cpp
blobb5ee4d726d9c7ab6b9fc41ce3569cff1af7924ee
1 #include <ail/file.hpp>
2 #include <ail/string.hpp>
3 #include <ail/environment.hpp>
5 #include <boost/filesystem.hpp>
7 namespace ail
9 file::file():
10 file_descriptor(0)
14 file::file(std::string const & name, open_mode_type mode):
15 file_descriptor(0)
17 open(name, mode);
20 file::~file()
22 close();
25 bool file::open()
27 return file_descriptor != 0;
30 bool file::open(std::string const & name, open_mode_type mode)
32 close();
34 std::string fopen_mode;
36 switch(mode)
38 case open_mode_read:
39 fopen_mode = "r";
40 break;
42 case open_mode_read_write:
43 fopen_mode = "r+";
44 break;
46 case open_mode_write_truncate:
47 fopen_mode = "w";
48 break;
50 case open_mode_read_write_truncate:
51 fopen_mode = "w+";
52 break;
55 fopen_mode += "b";
57 file_descriptor = std::fopen(name.c_str(), fopen_mode.c_str());
59 return file_descriptor != 0;
62 bool file::open_read_only(std::string const & name)
64 return open(name, open_mode_read);
67 bool file::open_create(std::string const & name)
69 return open(name, open_mode_read_write_truncate);
72 std::string file::read(std::size_t size)
74 if(size == 0)
75 return "";
77 char * buffer = new char[size];
78 read(buffer, size);
79 std::string output;
80 output.assign(buffer, size);
81 delete[] buffer;
82 return output;
85 void file::read(char * output, std::size_t size)
87 if(file_descriptor == 0)
88 throw exception("Trying to read from an unopened file");
90 std::size_t result = std::fread(output, 1, static_cast<int>(size), file_descriptor);
91 if(result == 0)
93 int fail = std::ferror(file_descriptor);
94 if(fail == 0)
95 throw exception("An unknown error occured while attempting to read from a file");
99 void file::write(std::string const & input)
101 write(input.c_str(), input.length());
104 void file::write(char const * input, std::size_t size)
106 if(file_descriptor == 0)
107 throw exception("Trying to write to an unopened file");
109 std::size_t result = std::fwrite(input, 1, size, file_descriptor);
110 if(result < size)
111 throw exception("Failed to write to file");
114 void file::close()
116 if(file_descriptor != 0)
118 std::fclose(file_descriptor);
119 file_descriptor = 0;
123 std::size_t file::get_size()
125 if(file_descriptor == 0)
126 throw exception("Cannot get the size of an unopened file");
128 fpos_t position;
129 int fail = std::fgetpos(file_descriptor, &position);
130 if(fail != 0)
131 throw exception("Failed to retrieve file pointer");
132 seek_end();
133 std::size_t output = static_cast<std::size_t>(std::ftell(file_descriptor));
134 fail = std::fsetpos(file_descriptor, &position);
135 if(fail != 0)
136 throw exception("Failed to set file pointer");
137 return output;
140 std::size_t file::get_file_pointer()
142 if(file_descriptor == 0)
143 throw exception("Trying to get the file pointer of an unopened file");
145 long position = std::ftell(file_descriptor);
146 if(position == -1)
147 throw exception("Failed to retrieve file pointer");
148 return static_cast<std::size_t>(position);
151 void file::set_file_pointer(std::size_t offset)
153 if(file_descriptor == 0)
154 throw exception("Trying to set the file pointer of an unopened file");
156 int fail = std::fseek(file_descriptor, static_cast<long>(offset), SEEK_SET);
157 if(fail != 0)
158 throw exception("Failed to set file pointer");
161 void file::seek_end()
163 if(file_descriptor == 0)
164 throw exception("Trying to seek the end of an unopened file");
166 int fail = std::fseek(file_descriptor, 0, SEEK_END);
167 if(fail != 0)
168 throw exception("Failed to seek end of file");
171 bool read_file(std::string const & file_name, std::string & output)
173 file file_object;
174 bool success = file_object.open_read_only(file_name);
175 if(!success)
176 return false;
177 std::size_t file_size = file_object.get_size();
178 output = file_object.read(file_size);
179 return true;
182 bool write_file(std::string const & file_name, std::string const & input)
184 file file_object;
185 bool success = file_object.open_create(file_name);
186 if(success == false)
187 return false;
188 file_object.write(input);
189 return true;
192 bool append_to_file(std::string const & file_name, std::string const & input)
194 file file_object;
196 !file_object.open(file_name) &&
197 !file_object.open_create(file_name)
199 return false;
200 file_object.seek_end();
201 file_object.write(input);
202 return true;
205 bool read_lines(std::string const & file_name, std::vector<std::string> & output)
207 std::string input;
208 bool result = read_file(file_name, input);
209 if(result == false)
210 return false;
211 input = erase_string(input, "\r");
212 output = tokenise(input, "\n");
213 return true;
216 bool create_directory(std::string const & path)
220 return boost::filesystem::create_directory(path);
222 catch(boost::exception &)
224 throw ail::exception("Unable to create directory");
228 bool read_directory(std::string const & directory, string_vector & files, string_vector & directories)
232 for(boost::filesystem::directory_iterator i(directory), end; i != end; i++)
234 std::string const & path = i->leaf();
235 if(boost::filesystem::is_directory(i->status()))
236 directories.push_back(path);
237 else
238 files.push_back(path);
241 catch(...)
243 return false;
245 return true;
248 bool rename_file(std::string const & target, std::string const & new_name)
252 boost::filesystem::rename(target, new_name);
254 catch(...)
256 return false;
258 return true;
261 bool remove_file(std::string const & path)
265 return boost::filesystem::remove(path);
267 catch(...)
269 return false;
273 std::string join_paths(std::string const & left, std::string const & right)
275 #ifdef AIL_WINDOWS
276 std::string const path_char = "\\";
277 #else
278 std::string const path_char = "/";
279 #endif
280 std::string output = left + path_char + right;
281 std::string const target = path_char + path_char;
282 for(std::size_t i = 0; i < 2; i++)
283 output = replace_string(output, target, path_char);
284 return output;
287 bool retrieve_extension(std::string const & path, std::string & output)
289 std::size_t offset = path.rfind('.');
290 if(offset == std::string::npos)
291 return false;
292 output = path.substr(offset + 1);
293 return true;
296 bool file_exists(std::string const & path)
298 file file_object;
299 return file_object.open(path, file::open_mode_read);