iutest  1.17.1.0
iutest_file.hpp
[詳解]
1 //======================================================================
2 //-----------------------------------------------------------------------
13 //-----------------------------------------------------------------------
14 //======================================================================
15 #ifndef INCG_IRIS_IUTEST_FILE_HPP_77D2C2B9_F504_4BB5_BA56_D97A2EB37DC6_
16 #define INCG_IRIS_IUTEST_FILE_HPP_77D2C2B9_F504_4BB5_BA56_D97A2EB37DC6_
17 
18 //======================================================================
19 // include
20 #include "iutest_internal_defs.hpp"
21 #include "iutest_stream.hpp"
22 
23 namespace iutest
24 {
25 
26 //======================================================================
27 // class
31 class IFile : public detail::IOutStream, public detail::IInStream
32 {
33 public:
35  enum OpenFlag
36  {
37  OpenRead = 0x00000001,
38  OpenWrite = 0x00000002,
39  OpenAppend = 0x00000003
40  };
41 public:
42  virtual ~IFile() {}
43 
44 public:
51  bool Open(const char* filename, int mode)
52  {
53  return OpenImpl(filename, mode);
54  }
55 
56 #if IUTEST_HAS_STD_FILESYSTEM
57 
63  bool Open(const ::std::filesystem::path& path, int mode)
64  {
65  return Open(path.string().c_str(), mode);
66  }
67 #endif
68 
70  virtual void Close() = 0;
71 private:
72  virtual bool OpenImpl(const char* filename, int mode) = 0;
73 };
74 
75 namespace detail
76 {
77 
81 class IFileSystem
82 {
83 public:
84  IFileSystem()
85  {
86  SetInstance(this);
87  }
88  virtual ~IFileSystem()
89  {
90  SetInstance(NULL);
91  }
92 
93 public:
94  virtual void Initialize() {}
95 
96 public:
97  static IFileSystem* GetInstance() { return GetInstanceVariable().pInstance; }
98 
99 public:
100  static IFile* New()
101  {
102  IFileSystem* fs = GetInstance();
103  if( fs == NULL )
104  {
105  return NULL;
106  }
107  IFile* p = fs->Create();
108  return p;
109  }
110  static void Free(IFile* ptr)
111  {
112  IFileSystem* fs = GetInstance();
113  if( fs == NULL )
114  {
115  return;
116  }
117  fs->Delete(ptr);
118  }
119 
120  static bool ReadAll(const char* filename, ::std::string& dst)
121  {
122  IFile* fp = detail::IFileSystem::New();
123  if(fp == NULL)
124  {
125  return false;
126  }
127 
128  if(!fp->Open(filename, IFile::OpenRead))
129  {
130  detail::IFileSystem::Free(fp);
131  return false;
132  }
133 
134  dst = fp->ReadAll();
135  detail::IFileSystem::Free(fp);
136  return true;
137  }
138 
139 private:
140  virtual IFile* Create() = 0;
141  virtual void Delete(IFile*) = 0;
142 
143 private:
144  struct InstanceVariable
145  {
146  IFileSystem* pInstance;
147  };
148 
149  static InstanceVariable& GetInstanceVariable() { static InstanceVariable v; return v; }
150  static void SetInstance(IFileSystem* pFileSystem) { GetInstanceVariable().pInstance = pFileSystem; }
151 };
152 
153 } // end of namespace detail
154 } // end of namespace iutest
155 
156 namespace iutest
157 {
158 
162 template<typename FILE>
163 class FileSystem : public detail::IFileSystem
164 {
165 private:
166  virtual IFile* Create() IUTEST_CXX_OVERRIDE { return new FILE; }
167  virtual void Delete(IFile* ptr) IUTEST_CXX_OVERRIDE { detail::Delete<FILE>(static_cast<FILE*>(ptr)); }
168 };
169 
170 
171 #if IUTEST_HAS_FOPEN
172 
176 class StdioFile : public IFile
177 {
178 protected:
179  FILE* m_fp;
180 public:
181  StdioFile() IUTEST_CXX_NOEXCEPT_SPEC : m_fp(NULL) {}
182  virtual ~StdioFile() { Close(); }
183 public:
187  virtual void Close() IUTEST_CXX_OVERRIDE
188  {
189  if( m_fp != NULL )
190  {
191  fclose(m_fp);
192  m_fp = NULL;
193  }
194  }
201  virtual bool Write(const void* buf, size_t size, size_t cnt) IUTEST_CXX_OVERRIDE
202  {
203  if( fwrite(buf, size, cnt, m_fp) < cnt )
204  {
205  return false;
206  }
207  if( fflush(m_fp) != 0 )
208  {
209  return false;
210  }
211  return true;
212  }
213 
220  virtual bool Read(void* buf, size_t size, size_t cnt) IUTEST_CXX_OVERRIDE
221  {
222  if( fread(buf, size, cnt, m_fp) < cnt )
223  {
224  return false;
225  }
226  return true;
227  }
228 
230  virtual size_t GetSize() IUTEST_CXX_OVERRIDE
231  {
232 #if IUTEST_HAS_FILE_STAT
233  return GetSize(m_fp);
234 #else
235  return GetSizeBySeekSet(m_fp);
236 #endif
237  }
238 
239 public:
240  static size_t GetSize(FILE* fp)
241  {
242  if( fp == NULL )
243  {
244  return 0;
245  }
246 #if IUTEST_HAS_FILE_STAT
247  internal::posix::StatStruct st;
248  if (internal::posix::Stat(fp, &st) != 0)
249  {
250  return GetSizeBySeekSet(fp);
251  }
252  // FIXME: https://github.com/srz-zumix/iutest/issues/227
253  return static_cast<size_t>(st.st_size);
254 #else
255  return GetSizeBySeekSet(fp);
256 #endif
257  }
258  static size_t GetSizeBySeekSet(FILE* fp)
259  {
260  if( fp == NULL )
261  {
262  return 0;
263  }
264  const long pre = ftell(fp);
265  if( (pre != -1) && (fseek(fp, 0, SEEK_END) == 0) )
266  {
267  const size_t size = static_cast<size_t>(ftell(fp));
268  IUTEST_UNUSED_RETURN(fseek(fp, pre, SEEK_SET));
269  return size;
270  }
271  return 0;
272  }
273 private:
274  virtual bool OpenImpl(const char* filename, int mode) IUTEST_CXX_OVERRIDE
275  {
276  Close();
277 IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_BEGIN()
278  switch( mode )
279  {
280  case IFile::OpenRead:
281  m_fp = fopen(filename, "rb");
282  break;
283  case IFile::OpenWrite:
284  m_fp = fopen(filename, "wb");
285  break;
286  case IFile::OpenAppend:
287  m_fp = fopen(filename, "ab");
288  break;
289  default:
290  break;
291  }
292 IUTEST_PRAGMA_CRT_SECURE_WARN_DISABLE_END()
293  return m_fp != NULL;
294  }
295 };
296 
297 class StdErrorFile : public StdioFile
298 {
299 public:
301  virtual ~StdErrorFile() { Close(); }
302 public:
306  virtual void Close() IUTEST_CXX_OVERRIDE
307  {
308  m_fp = NULL;
309  }
310 private:
311  virtual bool OpenImpl(const char* , int ) IUTEST_CXX_OVERRIDE
312  {
313  m_fp = stderr;
314  return true;
315  }
316 };
317 
318 #endif
319 
320 #if IUTEST_HAS_STRINGSTREAM
321 
325 class StringStreamFile : public IFile
326 {
327 public:
328  virtual ~StringStreamFile() { Close(); }
329 public:
333  virtual void Close() IUTEST_CXX_OVERRIDE
334  {
335  }
336 
343  virtual bool Write(const void* buf, size_t size, size_t cnt) IUTEST_CXX_OVERRIDE
344  {
345  for( size_t i=0; i < cnt; ++i )
346  {
347  ss.write(static_cast<const char*>(buf), size);
348  }
349  return true;
350  }
351 
358  virtual bool Read(void* buf, size_t size, size_t cnt) IUTEST_CXX_OVERRIDE
359  {
360  char* p = static_cast<char*>(buf);
361  for( size_t i = 0; i < cnt; ++i )
362  {
363  ss.read(p, size);
364  p += size;
365  }
366  return true;
367  }
368 
370  virtual size_t GetSize() IUTEST_CXX_OVERRIDE
371  {
372  ::std::stringstream::pos_type pre = ss.tellg();
373  ss.seekg(0, ::std::ios::end);
374  ::std::stringstream::pos_type size = ss.tellg();
375  ss.seekg(pre, ::std::ios::beg);
376  return static_cast<size_t>(size);
377  }
378 
380  virtual ::std::string ReadAll() IUTEST_CXX_OVERRIDE
381  {
382  return ss.str();
383  }
384 private:
385  virtual bool OpenImpl(const char* , int ) IUTEST_CXX_OVERRIDE
386  {
387  ss.clear();
388  return true;
389  }
390 protected:
391  ::std::stringstream ss;
392 };
393 
394 #endif
395 
396 namespace detail
397 {
398 
402 class NoEffectFile : public IFile
403 {
404 public:
405  virtual void Close() IUTEST_CXX_OVERRIDE {}
406  virtual bool Write(const void*, size_t, size_t) IUTEST_CXX_OVERRIDE { return true; }
407  virtual bool Read(void*, size_t, size_t) IUTEST_CXX_OVERRIDE { return true; }
408  virtual size_t GetSize() IUTEST_CXX_OVERRIDE { return 0; }
409 private:
410  virtual bool OpenImpl(const char*, int) IUTEST_CXX_OVERRIDE { return true; }
411 };
412 
413 } // end of namespace detail
414 } // end of namespace iutest
415 
416 #endif // INCG_IRIS_IUTEST_FILE_HPP_77D2C2B9_F504_4BB5_BA56_D97A2EB37DC6_
iutest::StringStreamFile::ReadAll
virtual ::std::string ReadAll() IUTEST_CXX_OVERRIDE
全読み込み
Definition: iutest_file.hpp:381
iutest::StringStreamFile
文字列バッファ書き込み IFile インターフェースクラス
Definition: iutest_file.hpp:326
iutest::StringStreamFile::Write
virtual bool Write(const void *buf, size_t size, size_t cnt) IUTEST_CXX_OVERRIDE
書き込み
Definition: iutest_file.hpp:344
iutest::StdioFile::GetSize
virtual size_t GetSize() IUTEST_CXX_OVERRIDE
サイズ取得
Definition: iutest_file.hpp:231
iutest_internal_defs.hpp
internal definition
iutest_stream.hpp
io stream
iutest_config.hpp
iris unit test config
IUTEST_CXX_NOEXCEPT_SPEC
#define IUTEST_CXX_NOEXCEPT_SPEC
noexcept specification definition
Definition: iutest_compiler.hpp:734
iutest
iutest root namespace
Definition: iutest_charcode.hpp:31
iutest::StdioFile::Close
virtual void Close() IUTEST_CXX_OVERRIDE
閉じる
Definition: iutest_file.hpp:188
iutest::IFile::OpenFlag
OpenFlag
ファイルオープンモードフラグ
Definition: iutest_file.hpp:36
iutest::StringStreamFile::GetSize
virtual size_t GetSize() IUTEST_CXX_OVERRIDE
サイズ取得
Definition: iutest_file.hpp:371
iutest::IFile::Close
virtual void Close()=0
閉じる
IUTEST_CXX_OVERRIDE
#define IUTEST_CXX_OVERRIDE
override definition
Definition: iutest_compiler.hpp:670
iutest::StdioFile::Read
virtual bool Read(void *buf, size_t size, size_t cnt) IUTEST_CXX_OVERRIDE
読み込み
Definition: iutest_file.hpp:221
iutest::IFile::OpenAppend
@ OpenAppend
追記
Definition: iutest_file.hpp:40
iutest::IFile::Open
bool Open(const char *filename, int mode)
開く
Definition: iutest_file.hpp:52
iutest::StdErrorFile::Close
virtual void Close() IUTEST_CXX_OVERRIDE
閉じる
Definition: iutest_file.hpp:307
iutest::IFile
ファイルクラスインターフェイス
Definition: iutest_file.hpp:32
iutest::IFile::OpenRead
@ OpenRead
読み込み
Definition: iutest_file.hpp:38
iutest::StringStreamFile::Read
virtual bool Read(void *buf, size_t size, size_t cnt) IUTEST_CXX_OVERRIDE
読み込み
Definition: iutest_file.hpp:359
iutest::StdioFile
標準ファイルクラス
Definition: iutest_file.hpp:177
iutest::FileSystem
ファイル処理クラスインターフェイス
Definition: iutest_file.hpp:164
iutest::StringStreamFile::Close
virtual void Close() IUTEST_CXX_OVERRIDE
閉じる
Definition: iutest_file.hpp:334
iutest::IFile::OpenWrite
@ OpenWrite
書き込み
Definition: iutest_file.hpp:39
iutest::StdErrorFile
Definition: iutest_file.hpp:298
iutest::StdioFile::Write
virtual bool Write(const void *buf, size_t size, size_t cnt) IUTEST_CXX_OVERRIDE
書き込み
Definition: iutest_file.hpp:202