1// Copyright 2014 The Android Open Source Project
2//
3// This software is licensed under the terms of the GNU General Public
4// License version 2, as published by the Free Software Foundation, and
5// may be copied, distributed, and modified under those terms.
6//
7// This program is distributed in the hope that it will be useful,
8// but WITHOUT ANY WARRANTY; without even the implied warranty of
9// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10// GNU General Public License for more details.
11
12#ifndef ANDROID_BASE_SCOPED_STDIO_FILE_H
13#define ANDROID_BASE_SCOPED_STDIO_FILE_H
14
15#include <stdio.h>
16
17namespace android {
18namespace base {
19
20// Helper class used to implement a scoped stdio FILE* pointer.
21// I.e. guarantees that the file is closed on scope exit, unless
22// the release() method is called. It is also possible to close
23// the file explicitly with close().
24class ScopedStdioFile {
25public:
26    // Default constructor, uses an empty file.
27    ScopedStdioFile() : mFile(NULL) {}
28
29    // Regular constructor, takes owneship of |file|.
30    explicit ScopedStdioFile(FILE* file) : mFile(file) {}
31
32    // Destructor always calls close().
33    ~ScopedStdioFile() { close(); }
34
35    // Returns FILE* pointer directly.
36    FILE* get() const { return mFile; }
37
38    // Release the FILE* handle and return it to the caller, which becomes
39    // its owner. Returns NULL if the instance was already closed or empty.
40    FILE* release() {
41        FILE* file = mFile;
42        mFile = NULL;
43        return file;
44    }
45
46    // Swap two scoped FILE* pointers.
47    void swap(ScopedStdioFile* other) {
48        FILE* tmp = other->mFile;
49        other->mFile = mFile;
50        mFile = tmp;
51    }
52
53    // Explicit close of a scoped FILE*.
54    void close() {
55        if (mFile) {
56            ::fclose(mFile);
57            mFile = NULL;
58        }
59    }
60private:
61    FILE* mFile;
62};
63
64}  // namespace base
65}  // namespace android
66
67#endif  // ANDROID_BASE_SCOPED_STDIO_FILE_H
68