- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

gfile.cpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2001-2013 Graeme Walker <graeme_walker@users.sourceforge.net>
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 3 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, see <http://www.gnu.org/licenses/>.
16 // ===
17 //
18 // gfile.cpp
19 //
20
21 #include "gdef.h"
22 #include "glimits.h"
23 #include "gfile.h"
24 #include "gprocess.h"
25 #include "glog.h"
26 #include <iostream>
27 #include <cstdio>
28
29 bool G::File::remove( const Path & path , const G::File::NoThrow & )
30 {
31 bool rc = 0 == std::remove( path.str().c_str() ) ;
32 G_DEBUG( "G::File::remove: \"" << path << "\": success=" << rc ) ;
33 return rc ;
34 }
35
36 void G::File::remove( const Path & path )
37 {
38 if( 0 != std::remove( path.str().c_str() ) )
39 {
40 //int error = G::Process::errno_() ;
41 throw CannotRemove( path.str() ) ;
42 }
43 G_DEBUG( "G::File::remove: \"" << path << "\"" ) ;
44 }
45
46 bool G::File::rename( const Path & from , const Path & to , const NoThrow & )
47 {
48 bool rc = 0 == std::rename( from.str().c_str() , to.str().c_str() ) ;
49 G_DEBUG( "G::File::rename: \"" << from << "\" -> \"" << to << "\": success=" << rc ) ;
50 return rc ;
51 }
52
53 void G::File::rename( const Path & from , const Path & to )
54 {
55 if( 0 != std::rename( from.str().c_str() , to.str().c_str() ) )
56 {
57 //int error = G::Process::errno_() ;
58 throw CannotRename( std::string() + "[" + from.str() + "] to [" + to.str() + "]" ) ;
59 }
60 G_DEBUG( "G::File::rename: \"" << from << "\" -> \"" << to << "\"" ) ;
61 }
62
63 void G::File::copy( const Path & from , const Path & to )
64 {
65 std::string reason = copy( from , to , 0 ) ;
66 if( !reason.empty() )
67 throw CannotCopy( std::string() + "[" + from.str() + "] to [" + to.str() + "]: " + reason ) ;
68 }
69
70 bool G::File::copy( const Path & from , const Path & to , const NoThrow & )
71 {
72 return copy(from,to,0).empty() ;
73 }
74
75 std::string G::File::copy( const Path & from , const Path & to , int )
76 {
77 std::ifstream in( from.str().c_str() , std::ios::binary | std::ios::in ) ;
78 if( !in.good() )
79 return "cannot open input file" ;
80
81 std::ofstream out( to.str().c_str() , std::ios::binary | std::ios::out | std::ios::trunc ) ;
82 if( !out.good() )
83 return "cannot open output file" ;
84
85 out << in.rdbuf() ;
86
87 if( in.fail() || in.bad() )
88 return "read error" ;
89
90 if( !out.good() )
91 return "write error" ;
92
93 in.close() ;
94 out.close() ;
95 if( sizeString(from) != sizeString(to) )
96 return "file size mismatch" ;
97
98 return std::string() ;
99 }
100
101 void G::File::copy( std::istream & in , std::ostream & out , std::streamsize limit , std::string::size_type block )
102 {
103 block = block ? block : static_cast<std::string::size_type>(limits::file_buffer) ;
104 std::vector<char> buffer ;
105 buffer.reserve( block ) ;
106
107 const std::streamsize b = static_cast<std::streamsize>(block) ;
108 std::streamsize size = 0U ;
109 while( ( limit == 0U || size < limit ) && in.good() && out.good() )
110 {
111 std::streamsize request = limit == 0U || (limit-size) > b ? b : (limit-size) ;
112 in.read( &buffer[0] , request ) ;
113 std::streamsize result = in.gcount() ;
114 if( result == 0U )
115 break ;
116 out.write( &buffer[0] , result ) ;
117 size += result ;
118 }
119
120 out.flush() ;
121 in.clear( in.rdstate() & ~std::ios_base::failbit ) ; // failbit set at eof so not useful
122 }
123
124 void G::File::mkdir( const Path & dir )
125 {
126 if( ! mkdir( dir , NoThrow() ) )
127 throw CannotMkdir( dir.str() ) ;
128 }
129
130 bool G::File::exists( const Path & path )
131 {
132 return exists( path , false , true ) ;
133 }
134
135 bool G::File::exists( const Path & path , const NoThrow & )
136 {
137 return exists( path , false , false ) ;
138 }
139
140 bool G::File::exists( const Path & path , bool on_error , bool do_throw )
141 {
142 bool enoent = false ;
143 bool rc = exists( path.str().c_str() , enoent ) ; // o/s-specific
144 if( !rc && enoent )
145 {
146 return false ;
147 }
148 else if( !rc && do_throw )
149 {
150 throw StatError( path.str() ) ;
151 }
152 else if( !rc )
153 {
154 return on_error ;
155 }
156 return true ;
157 }
158
159 bool G::File::chmodx( const Path & path , const NoThrow & )
160 {
161 return chmodx(path,false) ;
162 }
163
164 void G::File::chmodx( const Path & path )
165 {
166 chmodx(path,true) ;
167 }
168
169 bool G::File::mkdirs( const Path & path , const NoThrow & , int limit )
170 {
171 // (recursive)
172 G_DEBUG( "File::mkdirs: " << path ) ;
173 if( limit == 0 ) return false ;
174 if( exists(path) ) return true ;
175 if( path.str().empty() ) return true ;
176 if( ! mkdirs( path.dirname() , NoThrow() , limit-1 ) ) return false ;
177 bool ok = mkdir( path , NoThrow() ) ;
178 if( ok ) chmodx( path , NoThrow() ) ;
179 return ok ;
180 }
181
182 void G::File::mkdirs( const Path & path , int limit )
183 {
184 if( ! mkdirs(path,NoThrow(),limit) )
185 throw CannotMkdir(path.str()) ;
186 }
187
188 void G::File::create( const Path & path )
189 {
190 std::ofstream f( path.str().c_str() ) ;
191 f.close() ;
192 if( !exists(path) ) // race
193 throw CannotCreate( path.str() ) ;
194 }
195
G::Path::str
std::string str() const
Returns the path string.
Definition: gpath.cpp:135
G::File::copy
static bool copy(const Path &from, const Path &to, const NoThrow &)
Copies a file. Returns false on error.
Definition: gfile.cpp:70
glog.h
G::File::create
static void create(const Path &)
Creates an empty file. Throws on error.
Definition: gfile.cpp:188
md5::size_type
std::string::size_type size_type
A std::size_t type.
Definition: md5.h:43
G::File::rename
static bool rename(const Path &from, const Path &to, const NoThrow &)
Renames the file. Returns false on error.
Definition: gfile.cpp:46
glimits.h
G::File::mkdirs
static bool mkdirs(const Path &dir, const NoThrow &, int=100)
Creates a directory and all necessary parents.
Definition: gfile.cpp:169
gfile.h
gprocess.h
G::File::exists
static bool exists(const Path &file)
Returns true if the file (directory, link, device etc.) exists.
Definition: gfile.cpp:130
G::Path::dirname
Path dirname() const
Returns the drive/directory parts of the path.
Definition: gpath.cpp:182
G_DEBUG
#define G_DEBUG(expr)
Definition: glog.h:95
G::File::mkdir
static bool mkdir(const Path &dir, const NoThrow &)
Creates a directory. Returns false on error.
Definition: gfile_unix.cpp:30
G::File::remove
static bool remove(const Path &path, const NoThrow &)
Deletes the file or directory. Returns false on error.
Definition: gfile.cpp:29
G::File::NoThrow
An overload discriminator class for File methods.
Definition: gfile.h:56
G::File::chmodx
static void chmodx(const Path &file)
Makes the file executable.
Definition: gfile.cpp:164
G::Path
A Path object represents a file system path.
Definition: gpath.h:44
G::limits::file_buffer
Definition: glimits.h:44