Gobelijn API documentation  - generated for commit a0cbea7
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros Pages
file.h
Go to the documentation of this file.
1 #pragma once
2 /*
3  * This file is part of the gobelijn software.
4  * Gobelijn is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation, either version 3 of the License, or any later
7  * version. Gobelijn is distributed in the hope that it will be useful, but
8  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9  * or FITNESS FOR A PARTICULAR PURPOSE.
10  * See the GNU General Public License for details. You should have received
11  * a copy of the GNU General Public License along with the software. If not,
12  * see <http://www.gnu.org/licenses/>.
13  *
14  * Copyright 2016, 2018, Jan Broeckhove, Universiteit Antwerpen.
15  */
21 #include <cstdio>
22 #include <exception>
23 #include <string>
24 
25 namespace Raii {
26 
27 class FileError : public std::exception
28 {
29 };
30 class OpenError : public FileError
31 {
32 };
33 class CloseError : public FileError
34 {
35 };
36 class ReadError : public FileError
37 {
38 };
39 class WriteError : public FileError
40 {
41 };
42 
47 class File
48 {
49 public:
50  // Explicitly delete the usual constructors/assignment operators.
51  File() = delete;
52  File(const File&) = delete;
53  File& operator=(const File&) = delete;
54 
56  File(const char* path, const char* mode) : m_file(std::fopen(path, mode))
57  {
58  if (m_file == nullptr) {
59  throw OpenError();
60  }
61  }
62 
64  File(File&& other) noexcept
65  : m_file(other.m_file)
66  {
67  other.m_file = nullptr;
68  }
69 
71  File& operator=(File&& other)
72  {
73  m_file = other.m_file;
74  other.m_file = nullptr;
75  return *this;
76  }
77 
80  {
81  // Close the file, and hope that everything goes well. Don't throw an
82  // exception in the destructor, because that's dangerous and bad practice.
83  // If the user wants to handle exceptions, then they should use 'File::Close'.
84  CloseImpl();
85  }
86 
89  void Close()
90  {
91  if (!CloseImpl()) {
92  throw CloseError();
93  }
94  }
95 
97  bool IsOpen() const { return m_file != nullptr; }
98 
101  int ReadChar()
102  {
103  if (!IsOpen()) {
104  throw ReadError();
105  }
106  int result = std::fgetc(m_file);
107  if (std::ferror(m_file)) {
108  throw ReadError();
109  }
110  return result;
111  }
112 
114  void WriteChar(char Value) {
115  if (!IsOpen())
116  // File has been closed. Throw an exception.
117  throw WriteError();
118  if (std::fputc(Value, m_file) == EOF) {
119  throw WriteError();
120  }
121  }
122 
123 private:
126  bool CloseImpl()
127  {
128  if (!IsOpen())
129  // File has been closed already. Do nothing.
130  return true;
131  bool result = (std::fclose(m_file) == 0);
132  if (result) {
133  // Set the file handle to 'nullptr' if everything went well.
134  m_file = nullptr;
135  }
136  return result;
137  }
138 
139  std::FILE* m_file;
140 };
141 
142 } // namespace Raii
bool IsOpen() const
Checks if this file is still open.
Definition: file.h:97
std::FILE * m_file
Definition: file.h:139
A wrapper around the C FILE*-based IO API.
Definition: file.h:47
File(const char *path, const char *mode)
Opens the file at the given path.
Definition: file.h:56
int ReadChar()
Reads the next input character from this file.
Definition: file.h:101
void WriteChar(char Value)
Writes a single character to the file.
Definition: file.h:114
File & operator=(File &&other)
Moves the given file object's resources to this file object.
Definition: file.h:71
~File()
Performs clean-up for this File instance.
Definition: file.h:79
File(File &&other) noexcept
Creates a new file object from the file object's resources.
Definition: file.h:64
File()=delete
File & operator=(const File &)=delete
void Close()
Closes this file resource.
Definition: file.h:89
bool CloseImpl()
Closes this file resource.
Definition: file.h:126