stdio_file.h 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // std::FILE * wrapper
  2. //
  3. // Platform: ISO C++ 98/11
  4. // $Id$
  5. //
  6. // (c) __vic 2007
  7. #ifndef __VIC_STDIO_FILE_H
  8. #define __VIC_STDIO_FILE_H
  9. #include<__vic/defs.h>
  10. #include __VIC_SWAP_HEADER
  11. #include<cstdio>
  12. #include<string>
  13. namespace __vic {
  14. //////////////////////////////////////////////////////////////////////////////
  15. class stdio_file : private non_copyable
  16. {
  17. std::FILE *fp;
  18. public:
  19. explicit stdio_file(std::FILE *fp = nullptr) : fp(fp) {}
  20. stdio_file(const char *name, const char *mode) { open(name, mode); }
  21. ~stdio_file() { if(is_open()) std::fclose(fp); }
  22. #if __cpp_rvalue_references
  23. stdio_file(stdio_file &&o) noexcept : fp(o.fp) { o.fp = nullptr; }
  24. stdio_file &operator=(stdio_file &&o) noexcept { swap(o); return *this; }
  25. #endif
  26. bool open(const char *name, const char *mode)
  27. { return (fp = std::fopen(name, mode)); }
  28. bool is_open() const { return fp; }
  29. void close();
  30. bool close_nt() noexcept
  31. { int st = std::fclose(fp); fp = nullptr; return st == 0; }
  32. void swap(stdio_file &o) noexcept { std::swap(fp, o.fp); }
  33. std::FILE *attach_handle(std::FILE *f)
  34. { std::FILE *old = fp; fp = f; return old; }
  35. std::FILE *detach_handle() { return attach_handle(nullptr); }
  36. std::FILE *handle() const { return fp; }
  37. operator std::FILE*() const { return fp; }
  38. };
  39. //////////////////////////////////////////////////////////////////////////////
  40. __VIC_NORETURN void throw_stdio_read_error();
  41. __VIC_NORETURN void throw_stdio_write_error();
  42. //----------------------------------------------------------------------------
  43. inline bool read(std::FILE *fp, char &ch)
  44. {
  45. using namespace std; // cannot write "std::getc" if getc is a macro
  46. int c = getc(fp);
  47. if(c == EOF)
  48. {
  49. if(ferror(fp)) throw_stdio_read_error();
  50. return false; // feof(fp)
  51. }
  52. ch = c;
  53. return true;
  54. }
  55. //----------------------------------------------------------------------------
  56. inline bool read(std::FILE *fp, unsigned char &ch)
  57. {
  58. return read(fp, reinterpret_cast<char &>(ch));
  59. }
  60. //----------------------------------------------------------------------------
  61. inline void write(std::FILE *fp, char ch)
  62. {
  63. using namespace std; // cannot write "std::putc" if putc is a macro
  64. if(putc(ch, fp) == EOF) throw_stdio_write_error();
  65. }
  66. //----------------------------------------------------------------------------
  67. // Read std::string from C-stream
  68. bool getline(std::FILE * , std::string & , char = '\n');
  69. } // namespace
  70. #endif // header guard