Merge branch release-5-0 into release-5-1
[alexxy/gromacs.git] / src / gromacs / utility / file.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2012,2013,2014,2015, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS 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 GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 /*! \file
36  * \brief
37  * Declares gmx::File.
38  *
39  * \author Teemu Murtola <teemu.murtola@gmail.com>
40  * \inpublicapi
41  * \ingroup module_utility
42  */
43 #ifndef GMX_UTILITY_FILE_H
44 #define GMX_UTILITY_FILE_H
45
46 #include <cstdio>
47
48 #include <string>
49
50 #include "gromacs/utility/classhelpers.h"
51
52 namespace gmx
53 {
54
55 class File;
56
57 /*! \brief
58  * Parameters for creating a File object.
59  *
60  * This class (mostly) replaces the ability to return a File object from a
61  * function (since File is not copyable): returning a FileInitializer instead
62  * allows the caller to construct the File object.
63  *
64  * \inpublicapi
65  * \ingroup module_utility
66  */
67 class FileInitializer
68 {
69     public:
70         /*! \brief
71          * Creates the initializer with given parameters.
72          *
73          * The passed strings must remain valid until the initializer is used
74          * to construct a File object.
75          */
76         FileInitializer(const char *filename, const char *mode)
77             : filename_(filename), mode_(mode)
78         {
79         }
80
81     private:
82         const char *filename_;
83         const char *mode_;
84
85         /*! \brief
86          * Needed to allow access to the parameters without otherwise
87          * unnecessary accessors.
88          */
89         friend class File;
90 };
91
92 /*! \brief
93  * Basic file object.
94  *
95  * This class provides basic file I/O functionality and uses exceptions
96  * (FileIOError) for error reporting.
97  *
98  * \inpublicapi
99  * \ingroup module_utility
100  */
101 class File
102 {
103     public:
104         /*! \brief
105          * Opens a file and returns a `FILE` handle.
106          *
107          * \param[in] filename  Path of the file to open.
108          * \param[in] mode      Mode to open the file in (for fopen()).
109          * \throws    FileIOError on any I/O error.
110          *
111          * Instead of returning `NULL` on errors, throws an exception with
112          * additional details (including the file name and `errno`).
113          */
114         static FILE *openRawHandle(const char *filename, const char *mode);
115         //! \copydoc openRawHandle(const char *, const char *)
116         static FILE *openRawHandle(const std::string &filename, const char *mode);
117         /*! \brief
118          * Creates a file object and opens a file.
119          *
120          * \param[in] filename  Path of the file to open.
121          * \param[in] mode      Mode to open the file in (for fopen()).
122          * \throws    std::bad_alloc if out of memory.
123          * \throws    FileIOError on any I/O error.
124          *
125          * \see open(const char *, const char *)
126          */
127         File(const char *filename, const char *mode);
128         //! \copydoc File(const char *, const char *)
129         File(const std::string &filename, const char *mode);
130         /*! \brief
131          * Creates a file object and opens a file.
132          *
133          * \param[in] initializer  Parameters to open the file.
134          * \throws    std::bad_alloc if out of memory.
135          * \throws    FileIOError on any I/O error.
136          */
137         File(const FileInitializer &initializer);
138         /*! \brief
139          * Destroys the file object.
140          *
141          * If the file is still open, it is closed.
142          * Any error conditions will be ignored.
143          */
144         ~File();
145
146         /*! \brief
147          * Opens a file.
148          *
149          * \param[in] filename  Path of the file to open.
150          * \param[in] mode      Mode to open the file in (for fopen()).
151          * \throws    FileIOError on any I/O error.
152          *
153          * The file object must not be open.
154          */
155         void open(const char *filename, const char *mode);
156         //! \copydoc open(const char *, const char *)
157         void open(const std::string &filename, const char *mode);
158         /*! \brief
159          * Closes the file object.
160          *
161          * \throws  FileIOError on any I/O error.
162          *
163          * The file must be open.
164          */
165         void close();
166
167         /*! \brief
168          * Returns whether the file is an interactive terminal.
169          *
170          * Only works on Unix, otherwise always returns true.
171          * It only makes sense to call this for File::standardInput() and
172          * friends.
173          *
174          * Thie file must be open.
175          * Does not throw.
176          */
177         bool isInteractive() const;
178         /*! \brief
179          * Returns a file handle for interfacing with C functions.
180          *
181          * The file must be open.
182          * Does not throw.
183          */
184         FILE *handle();
185
186         /*! \brief
187          * Reads given number of bytes from the file.
188          *
189          * \param[out] buffer  Pointer to buffer that receives the bytes.
190          * \param[in]  bytes   Number of bytes to read.
191          * \throws     FileIOError on any I/O error.
192          *
193          * The file must be open.
194          */
195         void readBytes(void *buffer, size_t bytes);
196         /*! \brief
197          * Reads a single line from the file.
198          *
199          * \param[out] line    String to receive the line.
200          * \returns    false if nothing was read because the file ended.
201          * \throws     std::bad_alloc if out of memory.
202          * \throws     FileIOError on any I/O error.
203          *
204          * On error or when false is returned, \p line will be empty.
205          * Trailing space will be removed from the line.
206          * To loop over all lines in the file, use:
207          * \code
208            std::string line;
209            while (file.readLine(&line))
210            {
211                // ...
212            }
213            \endcode
214          */
215         bool readLine(std::string *line);
216         /*! \brief
217          * Reads a single line from the file.
218          *
219          * \param[out] line    String to receive the line.
220          * \returns    false if nothing was read because the file ended.
221          * \throws     std::bad_alloc if out of memory.
222          * \throws     FileIOError on any I/O error.
223          *
224          * On error or when false is returned, \p line will be empty.
225          * Works as readLine(), except that terminating newline will be present
226          * in \p line if it was present in the file.
227          *
228          * \see readLine()
229          */
230         bool readLineWithTrailingSpace(std::string *line);
231
232         /*! \brief
233          * Writes a string to the file.
234          *
235          * \param[in]  str  String to write.
236          * \throws     FileIOError on any I/O error.
237          *
238          * The file must be open.
239          */
240         void writeString(const char *str);
241         //! \copydoc writeString(const char *)
242         void writeString(const std::string &str) { writeString(str.c_str()); }
243         /*! \brief
244          * Writes a line to the file.
245          *
246          * \param[in]  line  Line to write.
247          * \throws     FileIOError on any I/O error.
248          *
249          * If \p line does not end in a newline, one newline is appended.
250          * Otherwise, works as writeString().
251          *
252          * The file must be open.
253          */
254         void writeLine(const char *line);
255         //! \copydoc writeLine(const char *)
256         void writeLine(const std::string &line) { writeLine(line.c_str()); }
257         /*! \brief
258          * Writes a newline to the file.
259          *
260          * \throws     FileIOError on any I/O error.
261          */
262         void writeLine();
263
264         /*! \brief
265          * Checks whether a file exists and is a regular file.
266          *
267          * \param[in] filename  Path to the file to check.
268          * \returns   true if \p filename exists and is accessible.
269          *
270          * Does not throw.
271          */
272         static bool exists(const char *filename);
273         //! \copydoc exists(const char *)
274         static bool exists(const std::string &filename);
275
276         /*! \brief
277          * Returns a File object for accessing stdin.
278          *
279          * \throws    std::bad_alloc if out of memory (only on first call).
280          */
281         static File &standardInput();
282         /*! \brief
283          * Returns a File object for accessing stdout.
284          *
285          * \throws    std::bad_alloc if out of memory (only on first call).
286          */
287         static File &standardOutput();
288         /*! \brief
289          * Returns a File object for accessing stderr.
290          *
291          * \throws    std::bad_alloc if out of memory (only on first call).
292          */
293         static File &standardError();
294
295         /*! \brief
296          * Reads contents of a file to a std::string.
297          *
298          * \param[in] filename  Name of the file to read.
299          * \returns   The contents of \p filename.
300          * \throws    std::bad_alloc if out of memory.
301          * \throws    FileIOError on any I/O error.
302          */
303         static std::string readToString(const char *filename);
304         //! \copydoc readToString(const char *)
305         static std::string readToString(const std::string &filename);
306         /*! \brief
307          * Convenience method for writing a file from a string in a single call.
308          *
309          * \param[in] filename  Name of the file to read.
310          * \param[in] text      String to write to \p filename.
311          * \throws    FileIOError on any I/O error.
312          *
313          * If \p filename exists, it is overwritten.
314          */
315         static void writeFileFromString(const std::string &filename,
316                                         const std::string &text);
317
318     private:
319         /*! \brief
320          * Initialize file object from an existing file handle.
321          *
322          * \param[in]  fp     %File handle to use (may be NULL).
323          * \param[in]  bClose Whether this object should close its file handle.
324          * \throws     std::bad_alloc if out of memory.
325          *
326          * Used internally to implement standardOutput() and standardError().
327          */
328         File(FILE *fp, bool bClose);
329
330         class Impl;
331
332         PrivateImplPointer<Impl> impl_;
333 };
334
335 } // namespace gmx
336
337 #endif