17ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// Copyright 2014 The Android Open Source Project 27ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// 37ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// This software is licensed under the terms of the GNU General Public 47ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// License version 2, as published by the Free Software Foundation, and 57ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// may be copied, distributed, and modified under those terms. 67ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// 77ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// This program is distributed in the hope that it will be useful, 87ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// but WITHOUT ANY WARRANTY; without even the implied warranty of 97ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 107ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// GNU General Public License for more details. 117ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 127ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#ifndef ANDROID_BASE_SCOPED_STDIO_FILE_H 137ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#define ANDROID_BASE_SCOPED_STDIO_FILE_H 147ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 157ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman#include <stdio.h> 167ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 177ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmannamespace android { 187ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmannamespace base { 197ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 207ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// Helper class used to implement a scoped stdio FILE* pointer. 217ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// I.e. guarantees that the file is closed on scope exit, unless 227ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// the release() method is called. It is also possible to close 237ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman// the file explicitly with close(). 247ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmanclass ScopedStdioFile { 257ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmanpublic: 267ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Default constructor, uses an empty file. 277ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman ScopedStdioFile() : mFile(NULL) {} 287ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 297ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Regular constructor, takes owneship of |file|. 307ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman explicit ScopedStdioFile(FILE* file) : mFile(file) {} 317ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 327ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Destructor always calls close(). 337ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman ~ScopedStdioFile() { close(); } 347ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 357ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Returns FILE* pointer directly. 367ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman FILE* get() const { return mFile; } 377ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 387ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Release the FILE* handle and return it to the caller, which becomes 397ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // its owner. Returns NULL if the instance was already closed or empty. 407ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman FILE* release() { 417ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman FILE* file = mFile; 427ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman mFile = NULL; 437ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman return file; 447ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman } 457ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 467ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Swap two scoped FILE* pointers. 477ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman void swap(ScopedStdioFile* other) { 487ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman FILE* tmp = other->mFile; 497ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman other->mFile = mFile; 507ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman mFile = tmp; 517ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman } 527ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 537ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman // Explicit close of a scoped FILE*. 547ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman void close() { 5557240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer if (mFile) { 5657240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer ::fclose(mFile); 577ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman mFile = NULL; 587ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman } 597ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman } 607ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukmanprivate: 617ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman FILE* mFile; 627ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman}; 637ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 647ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman} // namespace base 657ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman} // namespace android 667ae6ff442a26212a0cc4c1929b8b0a105dc988e4Misha Brukman 6757240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer#endif // ANDROID_BASE_SCOPED_STDIO_FILE_H 6857240ff6e2252f8986f6e47e4010bc52fbae25d1Benjamin Kramer