00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00018 #include <ders/file.hpp>
00019 #include <errno.h>
00020 #include <stdio.h>
00021 #include <ders/text_buf.hpp>
00022
00023 namespace ders {
00024
00025 void file::init()
00026 {
00027 fdr=-1;
00028 own=false;
00029 name->clear();
00030 err=ezero;
00031 }
00032
00033 file::file(mem_pool& m) : mp(m), name(nt(m))
00034 {
00035 init();
00036 }
00037
00038 file::file(mem_pool& m, const ch_rng& path, mode md, int fls) :
00039 mp(m), name(nt(m))
00040 {
00041 init();
00042 ex_open(path, md, fls);
00043 }
00044
00045 file::file(mem_pool& m, int fd) : mp(m), name(nt(m))
00046 {
00047 init();
00048 ex_attach(fd);
00049 }
00050
00051 file::~file()
00052 {
00053 if (is_owned() && is_opened()) close();
00054 }
00055
00056 bool file::open(const ch_rng& path, mode md, int fls)
00057 {
00058 assert(!is_opened());
00059
00060 fdr=fd::open(nt(mp, path)->c_str(), md, fls, err);
00061 if (fdr==-1) return false;
00062
00063 own=true;
00064 *name=path;
00065
00066 return true;
00067 }
00068
00069 bool file::close()
00070 {
00071 assert(is_owned());
00072
00073 bool rc=fd::close(fdr, err);
00074 if (!rc) return false;
00075
00076 init();
00077 return true;
00078 }
00079
00080 bool file::attach(int fd)
00081 {
00082 assert(!is_opened());
00083
00084 if (fd<0) {
00085 err=ebadf;
00086 return false;
00087 }
00088
00089 fdr=fd;
00090 own=false;
00091 *name=text_buf(mp)+"(attached to "+fdr+')';
00092 err=ezero;
00093
00094 return true;
00095 }
00096
00097 bool file::detach()
00098 {
00099 assert(is_opened());
00100
00101 init();
00102 return true;
00103 }
00104
00105 int file::read(void* buf, int n)
00106 {
00107 assert(n>=0);
00108
00109 if (n==0) {
00110 err=ezero;
00111 return 0;
00112 }
00113
00114 return fd::read(fdr, buf, n, err);
00115 }
00116
00117 int file::read(sh_text& buf, int n)
00118 {
00119 assert(n>=0);
00120
00121 buf->clear();
00122 buf->reserve(n);
00123
00124 int rc=read(buf->begin(), n);
00125 assert(rc<=n);
00126 if (rc!=-1) buf->uninitialized_resize(rc);
00127
00128 return rc;
00129 }
00130
00131 int file::write(const void* buf, int n)
00132 {
00133 assert(n>=0);
00134
00135 if (n==0) {
00136 err=ezero;
00137 return 0;
00138 }
00139
00140 return fd::write(fdr, buf, n, err);
00141 }
00142
00143 int file::seek(int off, whence wh)
00144 {
00145 return fd::seek(fdr, off, wh, err);
00146 }
00147
00148 void file::ex_is_ok() const
00149 {
00150 if (!is_ok()) {
00151 throw newFileErrorException(mp, _FLINE_, "File error", get_err(),
00152 get_name());
00153 }
00154 }
00155
00156 void file::ex_open(const ch_rng& path, mode md, int fls)
00157 {
00158 open(path, md, fls);
00159 if (!is_ok()) {
00160 throw newFileErrorException(mp, _FLINE_, "Can't open file", get_err(),
00161 path);
00162 }
00163 }
00164
00165 void file::ex_close()
00166 {
00167 close();
00168 if (!is_ok()) {
00169 throw newFileErrorException(mp, _FLINE_, "Can't close file", get_err(),
00170 get_name());
00171 }
00172 }
00173
00174 void file::ex_attach(int fd)
00175 {
00176 attach(fd);
00177 if (!is_ok()) {
00178 throw newFileErrorException(mp, _FLINE_, text_buf(mp)+"Can't attach to \""+
00179 fd+"\"", get_err(), get_name());
00180 }
00181 }
00182
00183 void file::ex_detach()
00184 {
00185 detach();
00186 if (!is_ok())
00187 throw newFileErrorException(mp, _FLINE_, "Can't detach", get_err(),
00188 get_name());
00189 }
00190
00191 int file::ex_read(void* buf, int n)
00192 {
00193 int rc=read(buf, n);
00194 if (!is_ok()) {
00195 throw newFileErrorException(mp, _FLINE_, "Can't read from file", get_err(),
00196 get_name());
00197 }
00198
00199 return rc;
00200 }
00201
00202 int file::ex_read(sh_text& buf, int n)
00203 {
00204 int rc=read(buf, n);
00205 if (!is_ok()) {
00206 throw newFileErrorException(mp, _FLINE_, "Can't read from file", get_err(),
00207 get_name());
00208 }
00209
00210 return rc;
00211 }
00212
00213 int file::ex_write(const void* buf, int n)
00214 {
00215 int rc=write(buf, n);
00216 if (!is_ok()) {
00217 throw newFileErrorException(mp, _FLINE_, "Can't write to file", get_err(),
00218 get_name());
00219 }
00220
00221 return rc;
00222 }
00223
00224 int file::ex_tell()
00225 {
00226 int rc=tell();
00227 if (!is_ok()) {
00228 throw newFileErrorException(mp, _FLINE_, "Can't tell on file", get_err(),
00229 get_name());
00230 }
00231
00232 return rc;
00233 }
00234
00235 int file::ex_seek(int off, whence wh)
00236 {
00237 int rc=seek(off, wh);
00238 if (!is_ok()) {
00239 throw newFileErrorException(mp, _FLINE_, "Can't seek on file", get_err(),
00240 get_name());
00241 }
00242
00243 return rc;
00244 }
00245
00246 sh_file new_file(mem_pool& mp)
00247 {
00248 mp_newbuf<file> buf(mp);
00249 return sh_file(buf.pool(), buf.rls(::new(buf.get()) file(buf.pool())));
00250 }
00251
00252 sh_file new_file(mem_pool& mp, const ch_rng& path, file::mode md, int fls)
00253 {
00254 mp_newbuf<file> buf(mp);
00255 return sh_file(buf.pool(), buf.rls(::new(buf.get()) file(buf.pool(), path, md,
00256 fls)));
00257 }
00258
00259 sh_file new_file(mem_pool& mp, int fd)
00260 {
00261 mp_newbuf<file> buf(mp);
00262 return sh_file(buf.pool(), buf.rls(::new(buf.get()) file(buf.pool(), fd)));
00263 }
00264
00265 shException newFileErrorException(mem_pool& mp, const FileLine& loc, const
00266 ch_rng& msg, error err, const ch_rng& fname)
00267 {
00268 return newFileErrorException(loc, msg, err, fname, shException(mp, 0));
00269 }
00270
00271 shException newFileErrorException(const FileLine& loc, const ch_rng& msg, error
00272 err, const ch_rng& fname, shException nest)
00273 {
00274 mp_newbuf<FileErrorException> buf(nest.pool());
00275 return shException(buf.pool(), buf.rls(::new(buf.get()) FileErrorException(loc,
00276 msg, err, fname, nest)));
00277 }
00278
00279 FileErrorException::FileErrorException(const FileLine& loc, const ch_rng& msg,
00280 error err, const ch_rng& fname, shException nest) :
00281 ErrorException(loc, msg, err, nest), fileName(nt(nest.pool(), fname))
00282 {
00283 }
00284
00285 sh_text FileErrorException::getClassName() const
00286 {
00287 return nt(message.pool(), "ders::FileErrorException");
00288 }
00289
00290 sh_text FileErrorException::toText() const
00291 {
00292 return text_buf(getClassName())+" ["+location.file+":"+location.line+
00293 "], errorCode="+errorCode+":\""+error_message(message.pool(), errorCode)+
00294 "\", fileName=\""+fileName+"\", message: "+message;
00295 }
00296
00297 error remove(mem_pool& mp, const ch_rng& fname)
00298 {
00299 return (::remove(text(mp, fname).c_str())==-1) ? convert_errno(errno) : ezero;
00300 }
00301
00302 void ex_remove(mem_pool& mp, const ch_rng& fname)
00303 {
00304 error err=remove(mp, fname);
00305 if (err!=ezero)
00306 throw newFileErrorException(mp, _FLINE_, "Can't remove file", err, fname);
00307 }
00308
00309 }
00310