Remove most using declarations from header files.
[ardour.git] / libs / pbd / filesystem.cc
1 /*
2         Copyright (C) 2007 Tim Mayberry 
3
4         This program is free software; you can redistribute it and/or modify
5         it under the terms of the GNU General Public License as published by
6         the Free Software Foundation; either version 2 of the License, or
7         (at your option) any later version.
8
9         This program is distributed in the hope that it will be useful,
10         but WITHOUT ANY WARRANTY; without even the implied warranty of
11         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12         GNU General Public License for more details.
13
14         You should have received a copy of the GNU General Public License
15         along with this program; if not, write to the Free Software
16         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 #include <sys/stat.h>
20
21 #include <glib.h>
22 #include <glib/gstdio.h>
23
24 #include <cerrno>
25 #include <fstream>
26
27 #include <glibmm/fileutils.h>
28 #include <glibmm/miscutils.h>
29
30 #include "pbd/filesystem.h"
31 #include "pbd/error.h"
32 #include "pbd/compose.h"
33
34 #include "i18n.h"
35
36 using namespace std;
37
38 namespace PBD {
39
40 namespace sys {
41         
42 path&
43 path::operator/=(const path& rhs)
44 {
45         m_path = Glib::build_filename(m_path, rhs.m_path);
46         return *this;
47 }
48
49 path&
50 path::operator/=(const string& rhs)
51 {
52         m_path = Glib::build_filename(m_path, rhs);
53         return *this;
54 }
55
56 path&
57 path::operator/=(const char* rhs)
58 {
59         m_path = Glib::build_filename(m_path, rhs);
60         return *this;
61 }
62
63 string
64 path::leaf () const
65 {
66         return Glib::path_get_basename(m_path);
67 }
68
69 path
70 path::branch_path () const
71 {
72         string dir = Glib::path_get_dirname (m_path);
73
74         /*
75          * glib returns "." to signify that the path
76          * has no directory components(branch path)
77          * whereas boost::filesystem returns an empty
78          * string
79          */
80         if(dir == ".")
81         {
82                 return "";
83         }
84         return dir;
85 }
86
87 bool
88 exists (const path & p)
89 {
90         return Glib::file_test (p.to_string(), Glib::FILE_TEST_EXISTS);
91 }
92
93 bool
94 is_directory (const path & p)
95 {
96         return Glib::file_test (p.to_string(), Glib::FILE_TEST_IS_DIR);
97 }
98
99 bool
100 create_directory(const path & p)
101 {
102         if(is_directory(p)) return false;
103
104         int error = g_mkdir (p.to_string().c_str(), S_IRWXU|S_IRWXG|S_IRWXO);
105
106         if(error == -1)
107         {
108                 throw filesystem_error(g_strerror(errno), errno);
109         }
110         return true;
111 }
112
113 bool
114 create_directories(const path & p)
115 {
116         if(is_directory(p)) return false;
117
118         int error = g_mkdir_with_parents (p.to_string().c_str(), S_IRWXU|S_IRWXG|S_IRWXO);
119
120         if(error == -1)
121         {
122                 throw filesystem_error(g_strerror(errno), errno);
123         }
124         return true;
125 }
126
127 bool
128 remove(const path & p)
129 {
130         if(!exists(p)) return false;
131
132         int error = g_unlink (p.to_string().c_str());
133
134         if(error == -1)
135         {
136                 throw filesystem_error(g_strerror(errno), errno);
137         }
138         return true;
139 }
140
141 void
142 rename (const path & from_path, const path & to_path)
143 {
144         // g_rename is a macro that evaluates to ::rename on
145         // POSIX systems, without the global namespace qualifier
146         // it would evaluate to a recursive call(if it compiled)
147         if ( ::g_rename( from_path.to_string().c_str(),
148                                 to_path.to_string().c_str() ) == -1 )
149         {
150                 throw filesystem_error(g_strerror(errno), errno);
151         }
152 }
153
154 // XXX character encoding.
155 void
156 copy_file(const path & from_path, const path & to_path)
157 {
158         std::ifstream in(from_path.to_string().c_str());
159         std::ofstream out(to_path.to_string().c_str());
160         
161         if (!in || !out) {
162                 throw filesystem_error(string_compose(_("Could not open files %1 and %2 for copying"),
163                                         from_path.to_string(), to_path.to_string()));
164         }
165         
166         out << in.rdbuf();
167         
168         if (!in || !out) {
169                 remove (to_path);
170                 throw filesystem_error(string_compose(_("Could not copy existing file %1 to %2"),
171                                         from_path.to_string(), to_path.to_string()));
172         }
173 }
174
175 string
176 basename (const path & p)
177 {
178         string base(p.leaf());
179
180         string::size_type n = base.rfind ('.');
181
182         return base.substr (0, n);
183 }
184
185 string
186 extension (const path & p)
187 {
188         string base(p.leaf());
189
190         string::size_type n = base.rfind ('.');
191
192         if (n != string::npos)
193         {
194                 return base.substr(n);
195         }
196
197         return string();
198
199 }
200
201 } // namespace sys
202
203 } // namespace PBD