1890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner// Copyright 2014 The Android Open Source Project 2890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner// 3890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner// This software is licensed under the terms of the GNU General Public 4890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner// License version 2, as published by the Free Software Foundation, and 5890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner// may be copied, distributed, and modified under those terms. 6890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner// 7890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner// This program is distributed in the hope that it will be useful, 8890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner// but WITHOUT ANY WARRANTY; without even the implied warranty of 9890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner// GNU General Public License for more details. 11890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner 12890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner#ifndef ANDROID_BASE_SCOPED_STDIO_FILE_H 13890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner#define ANDROID_BASE_SCOPED_STDIO_FILE_H 14890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner 15890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner#include <stdio.h> 16890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner 17890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turnernamespace android { 18890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turnernamespace base { 19890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner 20890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner// Helper class used to implement a scoped stdio FILE* pointer. 21890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner// I.e. guarantees that the file is closed on scope exit, unless 22890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner// the release() method is called. It is also possible to close 23890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner// the file explicitly with close(). 24890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turnerclass ScopedStdioFile { 25890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turnerpublic: 26890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner // Default constructor, uses an empty file. 27890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner ScopedStdioFile() : mFile(NULL) {} 28890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner 29890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner // Regular constructor, takes owneship of |file|. 30890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner explicit ScopedStdioFile(FILE* file) : mFile(file) {} 31890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner 32890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner // Destructor always calls close(). 33890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner ~ScopedStdioFile() { close(); } 34890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner 35890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner // Returns FILE* pointer directly. 36890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner FILE* get() const { return mFile; } 37890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner 38890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner // Release the FILE* handle and return it to the caller, which becomes 39890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner // its owner. Returns NULL if the instance was already closed or empty. 40890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner FILE* release() { 41890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner FILE* file = mFile; 42890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner mFile = NULL; 43890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner return file; 44890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner } 45890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner 46890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner // Swap two scoped FILE* pointers. 47890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner void swap(ScopedStdioFile* other) { 48890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner FILE* tmp = other->mFile; 49890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner other->mFile = mFile; 50890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner mFile = tmp; 51890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner } 52890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner 53890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner // Explicit close of a scoped FILE*. 54890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner void close() { 55890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner if (mFile) { 56890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner ::fclose(mFile); 57890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner mFile = NULL; 58890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner } 59890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner } 60890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turnerprivate: 61890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner FILE* mFile; 62890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner}; 63890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner 64890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner} // namespace base 65890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner} // namespace android 66890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner 67890f46464b0a35cbee882a5d62bd86a49879cabcDavid 'Digit' Turner#endif // ANDROID_BASE_SCOPED_STDIO_FILE_H 68