root/core/file.hpp

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. name
  2. mode
  3. check_open
  4. remove

   1 #ifndef libjmmcg_core_file_hpp
   2 #define libjmmcg_core_file_hpp
   3 
   4 /******************************************************************************
   5 ** $Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/core/file.hpp 2055 2017-05-13 19:35:47Z jmmcg $
   6 **
   7 ** Copyright (C) 2002 by J.M.McGuiness, coder@hussar.me.uk
   8 **
   9 ** This library is free software; you can redistribute it and/or
  10 ** modify it under the terms of the GNU Lesser General Public
  11 ** License as published by the Free Software Foundation; either
  12 ** version 2.1 of the License, or (at your option) any later version.
  13 **
  14 ** This library is distributed in the hope that it will be useful,
  15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17 ** Lesser General Public License for more details.
  18 **
  19 ** You should have received a copy of the GNU Lesser General Public
  20 ** License along with this library; if not, write to the Free Software
  21 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22 */
  23 
  24 /*
  25         Wrap up into a class creating a file, so that it is deleted upon object
  26         destruction. This class is completely ANSI.
  27 */
  28 
  29 #include "exception.hpp"
  30 #include <cassert>
  31 #include <fstream>
  32 #include <string>
  33 
  34 namespace jmmcg {
  35 
  36         typedef std::basic_fstream<tchar> tfstream;
  37         typedef std::basic_ifstream<tchar> tifstream;
  38         typedef std::basic_ofstream<tchar> tofstream;
  39 
  40         /**
  41                 This templating is done to generalise this class. Why? There are ASCII mode files and binary ones. ASCII mode translates the CR/LF combinations. Binary does not. Also it allows this class to manage Unicode character sets. (One that use double bytes for the character set.)
  42         */
  43         template <typename basic_file_type,ppd::generic_traits::api_type API_,typename Mdl_>
  44         class file : public basic_file_type, protected non_copyable {
  45         public:
  46                 typedef basic_file_type file_type;
  47                 typedef jmmcg::crt_exception<API_,Mdl_> exception_type;
  48 
  49                 file(const tstring &, const std::ios_base::openmode,const bool =true);
  50                 virtual ~file(void);
  51                 file &operator=(const file &);
  52                 // Why is "false" always returned? That's because comparing two files
  53                 // is non obvious: Do I compare the file names & the contents? What
  54                 // about the path to the two files? One may be relative, the other
  55                 // may be absolute. Even if they are the *same* file, but created with
  56                 // the names with these different paths they'll compare different,
  57                 // unless I do somethig very tricky with the path situation.
  58                 // Why am I going on about this? Well what if you want to create a set
  59                 // (or map) of these "File<...>" objects you could fall foul of the
  60                 // fact that they require "operator<(...)" to be defined. This in turn
  61                 // implies that "operator==(...)" is defined to do something sensible.
  62                 // If you don't like this, derive from this class and override the
  63                 // function.
  64                 virtual const bool operator==(const file &) const noexcept(true) {
  65                         return false;
  66                 }
  67 
  68                 const tstring &name(void) const noexcept(true) {
  69                         return fname;
  70                 }
  71 
  72         private:
  73                 bool auto_delete;
  74                 tstring fname;
  75                 std::ios_base::openmode mode;
  76 
  77                 void check_open(void);
  78                 void remove(void);
  79 
  80                 // I don't allow copying.
  81                 // Why? Well I need the file name for the current object to put the
  82                 // data from the input file object. How do I pass in this file name
  83                 // when the copy constructor only takes one parameter, and there's
  84                 // no way to pass in the destination file name. That's why I don't
  85                 // allow this.
  86                 explicit file(const tstring &) noexcept(true);
  87         };
  88 
  89         template<typename basic_file_type,ppd::generic_traits::api_type API_,typename Mdl_> inline
  90         file<basic_file_type,API_,Mdl_>::file(const tstring &nm, const std::ios_base::openmode flags,const bool ad)
  91         : basic_file_type(nm.c_str(), flags), auto_delete(ad), fname(nm), mode(flags) {
  92                 check_open();
  93         }
  94 
  95         template<typename basic_file_type,ppd::generic_traits::api_type API_,typename Mdl_> inline
  96         file<basic_file_type,API_,Mdl_>::~file(void) {
  97                 if (auto_delete) {
  98                         remove();
  99                 }
 100         }
 101 
 102         template<typename basic_file_type,ppd::generic_traits::api_type API_,typename Mdl_> inline file<basic_file_type,API_,Mdl_> &
 103         file<basic_file_type,API_,Mdl_>::operator=(const file<basic_file_type,API_,Mdl_> &tf) {
 104                 remove();
 105                 open(tf.fname,mode|=std::ios_base::out);
 106                 check_open();
 107                 file_type::operator<<(tf.rdbuf());
 108                 return *this;
 109         }
 110 
 111         template<typename basic_file_type,ppd::generic_traits::api_type API_,typename Mdl_> inline void
 112         file<basic_file_type,API_,Mdl_>::check_open(void) noexcept(false) {
 113                 if (!file_type::is_open()) {
 114                         jmmcg::info::function desc(__LINE__,__PRETTY_FUNCTION__,typeid(&file<basic_file_type,API_,Mdl_>::check_open),info::function::argument(_T("file name"),fname));
 115                         desc.add_arg(info::function::argument(_T("open mode"), mode));
 116                         throw exception(_T("Failed to open the specified file."), desc, JMMCG_REVISION_HDR(_T("$Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/core/file.hpp 2055 2017-05-13 19:35:47Z jmmcg $")));
 117                 }
 118         }
 119 
 120         template<typename basic_file_type,ppd::generic_traits::api_type API_,typename Mdl_> inline void
 121         file<basic_file_type,API_,Mdl_>::remove(void) noexcept(false) {
 122                 file_type::close();
 123                 if (::remove(fname.c_str())) {
 124                         throw exception(_T("Failed to delete the specified file."), jmmcg::info::function(__LINE__,__PRETTY_FUNCTION__,typeid(&file<basic_file_type,API_,Mdl_>::remove), info::function::argument(_T("file name"), fname)), JMMCG_REVISION_HDR(_T("$Header: svn+ssh://jmmcg@svn.code.sf.net/p/libjmmcg/code/trunk/libjmmcg/core/file.hpp 2055 2017-05-13 19:35:47Z jmmcg $")));
 125                 }
 126         }
 127 
 128 }
 129 
 130 #endif

/* [<][>][^][v][top][bottom][index][help] */