Marine Library  1.0
C++ library for Linux Networking Development
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
file.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Zhao DAI <daidodo@gmail.com>
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 any
7  * 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 accompanying file LICENSE.txt
16  * or <http://www.gnu.org/licenses/>.
17  */
18 
25 #ifndef DOZERG_FILE_H_20120119
26 #define DOZERG_FILE_H_20120119
27 
28 #include <sys/stat.h>
29 #include <sys/types.h>
30 #include <unistd.h>
31 #include <fcntl.h>
32 #include <errno.h>
33 #include <cstdio>
34 #include <string>
35 #include <vector>
36 #include "tools/system.hh" //ErrorMsg
37 
38 NS_SERVER_BEGIN
39 
43 class IFileDesc
44 {
45 public:
46  static const int kInvalidFd = -1;
51  static std::string ErrMsg(){return tools::ErrorMsg(errno);}
55  IFileDesc():fd_(kInvalidFd){}
60  virtual ~IFileDesc(){this->close();}
65  bool valid() const{return (fd_ >= 0);}
70  int fd() const{return fd_;}
87  virtual int fdType() const = 0;
93  virtual const char * fdTypeName() const = 0;
99  std::string filename() const{return tools::GetFilenameByFd(fd_);}
107  off_t length() const{
108  if(!valid())
109  return -1;
110  struct stat st;
111  if(0 != ::fstat(fd(), &st))
112  return -1;
113  return st.st_size;
114  }
121  bool deleted() const{
122  if(!valid())
123  return false;
124  struct stat st;
125  if(0 != ::fstat(fd(), &st))
126  return false;
127  return (0 == st.st_nlink);
128  }
137  bool block(bool on){
138  if(!valid())
139  return false;
140  const int oldflag = ::fcntl(fd_, F_GETFL);
141  if(-1 == oldflag)
142  return false;
143  const int newflag = (on ? oldflag & ~O_NONBLOCK : oldflag | O_NONBLOCK);
144  if(oldflag == newflag)
145  return true;
146  if(::fcntl(fd_, F_SETFL, newflag) < 0)
147  return false;
148  return true;
149  }
153  void close(){
154  if(valid()){
155  ::close(fd_);
156  fd_ = kInvalidFd;
157  }
158  }
163  virtual std::string toString() const{
164  CToString oss;
165  oss<<"{fd_="<<fd_<<"("<<fdTypeName()<<")"
166  <<"}";
167  return oss.str();
168  }
169 private:
170  //NOTE: Subclasses could implement its own copy and assignment operations
171  IFileDesc(const IFileDesc & other);
172  IFileDesc & operator =(const IFileDesc & other);
173 protected:
174  //member
175  int fd_;
176 };
177 
181 class CFile : public IFileDesc
182 {
183  typedef IFileDesc __MyBase;
184 protected:
185  static const int kFlagsDefault = O_RDONLY;
186  static const int kModeDefault = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
187 public:
188  static const int kFdType = 1;
195  static bool Unlink(const std::string & pathname){
196  if(pathname.empty())
197  return false;
198  return (0 == ::unlink(pathname.c_str()));
199  }
207  static bool Rename(const std::string & oldfile, const std::string & newfile){
208  if(oldfile.empty() || newfile.empty())
209  return false;
210  return (0 == ::rename(oldfile.c_str(), newfile.c_str()));
211  }
215  CFile(){}
224  explicit CFile(const char * pathname, int flags = kFlagsDefault, mode_t mode = kModeDefault){
225  this->open(pathname, flags, mode);
226  }
227  explicit CFile(const std::string & pathname, int flags = kFlagsDefault, mode_t mode = kModeDefault){
228  this->open(pathname, flags, mode);
229  }
230  //TODO: unit test
231  virtual bool open(const char * pathname, int flags = kFlagsDefault, mode_t mode = kModeDefault){
232  if(NULL == pathname)
233  return false;
234  if(valid())
235  this->close();
236  fd_ = ::open(pathname, flags, mode);
237  return valid();
238  }
239  virtual bool open(const std::string & pathname, int flags = kFlagsDefault, mode_t mode = kModeDefault){
240  return this->open(pathname.c_str(), flags, mode);
241  }
248  CFile(const CFile & other){copyFrom(other);}
249  CFile & operator =(const CFile & other){
250  copyFrom(other);
251  return *this;
252  }
254  int fdType() const{return kFdType;}
259  const char * fdTypeName() const{return "CFile";}
276  ssize_t read(char * buf, size_t size){
277  if(!valid())
278  return -1;
279  return ::read(fd(), buf, size);
280  }
284  bool read(std::vector<char> & buf, size_t size, bool append){
285  return readData(buf, size, append);
286  }
290  bool read(std::string & buf, size_t size, bool append){
291  return readData(buf, size, append);
292  }
303  ssize_t write(const char * buf, size_t size){
304  if(!valid())
305  return -1;
306  return ::write(fd(), buf, size);
307  }
308  ssize_t write(const std::vector<char> & buf){
309  return this->write(&buf[0], buf.size());
310  }
311  ssize_t write(const std::string & buf){
312  return this->write(&buf[0], buf.size());
313  }
328  bool seek(off_t offset, int whence){
329  if(!valid())
330  return false;
331  return ((off_t)-1 != ::lseek(fd(), offset, whence));
332  }
333 #ifdef __HAS_LSEEK64
334  bool seek64(off64_t offset, int whence){
335  if(!valid())
336  return false;
337  return ((off_t)-1 != ::lseek64(fd(), offset, whence));
338  }
339 #endif
340 
349  off_t tell() const{
350  if(!valid())
351  return -1;
352  return ::lseek(fd(), 0, SEEK_CUR);
353  }
354 #ifdef __HAS_LSEEK64
355  off64_t tell64() const{
356  if(!valid())
357  return -1;
358  return ::lseek64(fd(), 0, SEEK_CUR);
359  }
360 #endif
361 
362 #ifdef __HAS_FTRUNCATE
363 
370  bool truncate(off_t length){
371  if(!valid())
372  return false;
373  return (0 == ::ftruncate(fd(), length));
374  }
375 #endif
376 
381  virtual bool unlink(){
382  if(!valid())
383  return false;
384  return Unlink(__MyBase::filename());
385  }
392  bool rename(const std::string & newfile){
393  if(!valid() || newfile.empty())
394  return false;
395  std::string fname = __MyBase::filename();
396  if(fname.empty())
397  return false;
398  return Rename(fname, newfile);
399  }
400  std::string toString() const{
401  CToString oss;
402  oss<<"{IFileDesc="<<IFileDesc::toString()
403  <<", filename="<<filename()
404  <<"}";
405  return oss.str();
406  }
407 protected:
408  void copyFrom(const CFile & other){
409  if(!other.valid()){
410  this->close();
411  }else if(!valid()){
412  fd_ = ::dup(other.fd());
413  }else
414  fd_ = ::dup2(other.fd(), fd_);
415  }
416 private:
417  template<class Buf>
418  bool readData(Buf & buf, size_t size, bool append){
419  if(!valid())
420  return false;
421  const size_t from = (append ? buf.size() : 0);
422  buf.resize(from + size);
423  const ssize_t ret = this->read(&buf[from], size);
424  buf.resize(from + (ret > 0 ? ret : 0));
425  return (ret >= 0);
426  }
427 };
428 
429 NS_SERVER_END
430 
431 #endif
432 
virtual std::string toString() const
Get readable description of this object.
Definition: file.hh:163
int fdType() const
Get type id of this object.
Definition: file.hh:254
std::string toString() const
Get readable description of this object.
Definition: file.hh:400
virtual const char * fdTypeName() const =0
Get type name of this object.
bool valid() const
Test if this object is a valid file descriptor.
Definition: file.hh:65
bool deleted() const
Test if file is deleted.
Definition: file.hh:121
Abstract interface of fd (file descriptor).
Definition: file.hh:43
Definition: to_string.hh:43
static bool Unlink(const std::string &pathname)
Remove a file.
Definition: file.hh:195
IFileDesc()
Construct a default object.
Definition: file.hh:55
static std::string ErrMsg()
Get latest errno and error message.
Definition: file.hh:51
ssize_t read(char *buf, size_t size)
Definition: file.hh:276
virtual ~IFileDesc()
Destroy this object.
Definition: file.hh:60
Regular file operations.
Definition: file.hh:181
static bool Rename(const std::string &oldfile, const std::string &newfile)
Rename a file.
Definition: file.hh:207
void close()
Close this fd.
Definition: file.hh:153
virtual bool unlink()
Remove file.
Definition: file.hh:381
int fd() const
Get fd (file descriptor).
Definition: file.hh:70
bool block(bool on)
Set block/non-block for operations.
Definition: file.hh:137
bool read(std::vector< char > &buf, size_t size, bool append)
Definition: file.hh:284
bool rename(const std::string &newfile)
Rename file.
Definition: file.hh:392
virtual int fdType() const =0
Get type id of this object.
bool read(std::string &buf, size_t size, bool append)
Definition: file.hh:290
CFile()
Default constructor.
Definition: file.hh:215
const char * fdTypeName() const
Get readable description of this object.
Definition: file.hh:259
off_t length() const
Get byte size of file opened by this object.
Definition: file.hh:107
std::string filename() const
Get file name opened by this object.
Definition: file.hh:99